diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/util/TargetDataTypeConverter.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/util/TargetDataTypeConverter.java index 33a7c7eac3..9d14d77dcb 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/util/TargetDataTypeConverter.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/util/TargetDataTypeConverter.java @@ -27,6 +27,7 @@ import ghidra.dbg.target.TargetDataTypeMember; import ghidra.dbg.target.TargetNamedDataType; import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.util.Msg; public class TargetDataTypeConverter { @@ -481,6 +482,8 @@ public class TargetDataTypeConverter { case SINT: return AbstractIntegerDataType.getSignedDataType(tPrimitive.getLength(), dtm); case FLOAT: + // TODO: lookup by length must use "raw" encoding size since "aligned" lengths + // may be duplicated across different float types. return AbstractFloatDataType.getFloatDataType(tPrimitive.getLength(), dtm); case COMPLEX: return AbstractComplexDataType.getComplexDataType(tPrimitive.getLength(), dtm); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/symbol/AbstractDBTraceVariableSymbol.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/symbol/AbstractDBTraceVariableSymbol.java index 61ae964733..e4e6c8675e 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/symbol/AbstractDBTraceVariableSymbol.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/symbol/AbstractDBTraceVariableSymbol.java @@ -23,8 +23,8 @@ import db.DBRecord; import ghidra.program.database.data.DataTypeUtilities; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; -import ghidra.program.model.data.AbstractFloatDataType; import ghidra.program.model.data.DataType; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.program.model.pcode.Varnode; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java index dfe3b01571..bb550afa54 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java @@ -126,22 +126,51 @@ public class CreateDataBackgroundCmd extends BackgroundCommand { return true; } + private static Address alignAddress(Address addr, int alignment) { + if (addr == null) { + return null; + } + long mod = addr.getOffset() % alignment; + if (mod == 0) { + return addr; + } + try { + return addr.addNoWrap(alignment - mod); + } + catch (AddressOverflowException e) { + // ignore + } + return null; + } + private void createData(Address start, Address end, DataType dataType, Program p, - TaskMonitor monitor) throws AddressOverflowException, CodeUnitInsertionException { + TaskMonitor monitor) throws CodeUnitInsertionException { + + int alignment = 1; + if (newDataType.getLength() != newDataType.getAlignedLength()) { + // datatypes whose length does not match their aligned-length must + // be properly aligned to account for padding (e.g., x86-32 80-bit floats) + alignment = newDataType.getAlignment(); + } + + int initialProgress = bytesApplied; Listing listing = p.getListing(); listing.clearCodeUnits(start, end, false); - int length = (int) end.subtract(start) + 1; - while (start.compareTo(end) <= 0) { + Address nextAddr = alignAddress(start, alignment); + int length = (int) end.subtract(nextAddr) + 1; + while (nextAddr != null && nextAddr.compareTo(end) <= 0) { if (monitor.isCancelled()) { return; } - Data d = listing.createData(start, dataType, length); - int dataLen = d.getLength(); - start = start.addNoWrap(dataLen); - length -= dataLen; - bytesApplied += dataLen; + Data d = listing.createData(nextAddr, dataType, length); + Address maxDataAddr = d.getMaxAddress(); + bytesApplied = initialProgress + (int) maxDataAddr.subtract(start) + 1; + nextAddr = alignAddress(maxDataAddr.next(), alignment); + if (nextAddr != null) { + length = (int) end.subtract(nextAddr) + 1; + } monitor.setProgress(bytesApplied); if (++numDataCreated % 10000 == 0) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java index f0b6751017..23a1a9be29 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java @@ -133,7 +133,7 @@ public class CreateDataInStructureBackgroundCmd extends BackgroundCommand { // MemBuffer memBuf = new ProgramStructureProviderContext(program,addr, // struct, struct.getComponent(index).getOffset()); DataTypeInstance dti = - DataTypeInstance.getDataTypeInstance(newDataType, length); + DataTypeInstance.getDataTypeInstance(newDataType, length, true); if (dti == null || dti.getLength() > length) { break; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java index 62ab576b35..2db0b3fa8d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java @@ -114,7 +114,8 @@ public class CreateDataInStructureCmd implements Command { else { // MemBuffer memBuf = new ProgramStructureProviderContext(program,addr, // struct, dataComp.getParentOffset()); - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(newDataType, -1); + DataTypeInstance dti = + DataTypeInstance.getDataTypeInstance(newDataType, -1, true); struct.replace(index, dti.getDataType(), dti.getLength()); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorModel.java index 1c795f79d8..4a8b7bbf1d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorModel.java @@ -212,7 +212,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen } DataType resultDt = DataUtilities.reconcileAppliedDataType(currentDt, dt, true); - int resultLen = resultDt.getLength(); + int resultLen = resultDt.getAlignedLength(); if (resultDt instanceof Dynamic) { resultLen = DataTypeHelper.requestDtSize(getProvider(), resultDt.getDisplayName(), @@ -222,7 +222,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen throw new InvalidDataTypeException("Data types of size 0 are not allowed."); } - return DataTypeInstance.getDataTypeInstance(resultDt, resultLen); + return DataTypeInstance.getDataTypeInstance(resultDt, resultLen, true); } /** @@ -1172,7 +1172,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen dtName = dt.getDisplayName(); if (dtString.equals(dtName)) { return DataTypeInstance.getDataTypeInstance(element.getDataType(), - element.getLength()); + element.getLength(), true); } } @@ -1204,7 +1204,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen if (maxLength > 0 && newLength > maxLength) { throw new UsrException(newDt.getDisplayName() + " doesn't fit."); } - return DataTypeInstance.getDataTypeInstance(newDt, newLength); + return DataTypeInstance.getDataTypeInstance(newDt, newLength, true); } @SuppressWarnings("unused") // the exception is thrown by subclasses diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerModel.java index 83acb51fb7..a27044bf12 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerModel.java @@ -570,7 +570,8 @@ abstract class CompositeViewerModel extends AbstractTableModel else if (columnIndex == getDataTypeColumn()) { DataType dt = dtc.getDataType(); int dtLen = dt.getLength(); - return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength()); + return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(), + true); } else if (columnIndex == getNameColumn()) { value = dtc.getFieldName(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/DataTypeHelper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/DataTypeHelper.java index 3cad1320c8..3e4a4a69cc 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/DataTypeHelper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/DataTypeHelper.java @@ -146,7 +146,7 @@ public class DataTypeHelper { throw new InvalidDataTypeException( "Data type " + dt.getDisplayName() + " has no size and is not allowed."); } - return DataTypeInstance.getDataTypeInstance(dt, dtLen); + return DataTypeInstance.getDataTypeInstance(dt, dtLen, true); } public static int requestDtSize(CompositeEditorProvider provider, String dtName, @@ -203,7 +203,7 @@ public class DataTypeHelper { int maxBytes = model.getMaxReplaceLength(index); return requestBytes(model, dt, maxBytes); } - return DataTypeInstance.getDataTypeInstance(dt, length); + return DataTypeInstance.getDataTypeInstance(dt, length, true); } public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType dt, @@ -228,7 +228,7 @@ public class DataTypeHelper { if (size >= 1) { model.setLastNumBytes(size); - return DataTypeInstance.getDataTypeInstance(dt, size); + return DataTypeInstance.getDataTypeInstance(dt, size, true); } return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/InsertUndefinedAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/InsertUndefinedAction.java index abafcab546..89cdcf2d08 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/InsertUndefinedAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/InsertUndefinedAction.java @@ -59,7 +59,8 @@ public class InsertUndefinedAction extends CompositeEditorTableAction { DataType undefinedDt = model.viewComposite.isPackingEnabled() ? Undefined1DataType.dataType : DataType.DEFAULT; - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(undefinedDt, -1); + DataTypeInstance dti = + DataTypeInstance.getDataTypeInstance(undefinedDt, -1, false); model.insert(index, dti.getDataType(), dti.getLength()); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java index 362a1813ed..da56b5b09b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java @@ -161,7 +161,8 @@ class StructureEditorModel extends CompEditorModel { else if (columnIndex == getDataTypeColumn()) { DataType dt = dtc.getDataType(); int dtLen = dt.getLength(); - return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength()); + return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(), + true); } else if (columnIndex == getNameColumn()) { value = dtc.getFieldName(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/CreateArrayAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/CreateArrayAction.java index a9af994281..35061eea45 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/CreateArrayAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/CreateArrayAction.java @@ -141,7 +141,7 @@ class CreateArrayAction extends ListingContextAction { } int length = sel.getByteLength(); - int numElements = length / dt.getLength(); + int numElements = length / dt.getAlignedLength(); Command cmd = new CreateArrayInStructureCmd(from.getAddress(), numElements, dt, from.getComponentPath()); @@ -161,7 +161,7 @@ class CreateArrayAction extends ListingContextAction { } length += dtc.getLength(); } - return length / dt.getLength(); + return length / dt.getAlignedLength(); } private int getMaxElements(Structure struct, int index, DataType dt) { @@ -171,7 +171,7 @@ class CreateArrayAction extends ListingContextAction { DataTypeComponent dtc = struct.getComponent(index++); length += dtc.getLength(); } - return length / dt.getLength(); + return length / dt.getAlignedLength(); } private void createArrayAtAddress(Program program, Address addr) { @@ -210,10 +210,13 @@ class CreateArrayAction extends ListingContextAction { return; } DataType dt = data.getDataType(); - int dtLength = data.getLength(); + int elementLength = data.getLength(); + if (!(dt instanceof Dynamic)) { + elementLength = dt.getAlignedLength(); + } int length = (int) range.getLength(); - int numElements = length / dtLength; - CreateArrayCmd cmd = new CreateArrayCmd(addr, numElements, dt, dtLength); + int numElements = length / elementLength; + CreateArrayCmd cmd = new CreateArrayCmd(addr, numElements, dt, elementLength); if (!tool.execute(cmd, program)) { tool.setStatusInfo(cmd.getStatusMsg()); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java index 835c92196d..191b4aefd1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java @@ -501,7 +501,7 @@ public class DataPlugin extends Plugin implements DataService { } DataTypeInstance dataTypeInstance = DataTypeInstance.getDataTypeInstance(dataType, - new DumbMemBufferImpl(program.getMemory(), start)); + new DumbMemBufferImpl(program.getMemory(), start), false); if (dataTypeInstance == null) { tool.setStatusInfo("Unallowed data type at " + start + ": " + dataType.getName()); return -1; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataOrganizationPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataOrganizationPanel.java deleted file mode 100644 index 4e1213e488..0000000000 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataOrganizationPanel.java +++ /dev/null @@ -1,494 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.datamgr; - -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import docking.widgets.checkbox.GCheckBox; -import docking.widgets.label.GLabel; -import ghidra.program.model.data.DataOrganizationImpl; -import ghidra.util.layout.PairLayout; - -public class DataOrganizationPanel extends JPanel { - - JCheckBox charIsSignedCheckbox; - JTextField charSizeComponent; - JTextField wcharSizeComponent; - JTextField shortSizeComponent; - JTextField integerSizeComponent; - JTextField longSizeComponent; - JTextField longLongSizeComponent; - JTextField floatSizeComponent; - JTextField doubleSizeComponent; - JTextField longDoubleSizeComponent; - - JTextField absoluteMaxAlignComponent; - JTextField machineAlignComponent; - JTextField defaultAlignComponent; - JTextField pointerAlignComponent; - - DataOrganizationImpl dataOrganization; - - public DataOrganizationPanel() { - super(new PairLayout(3, 5)); - setUpAbsoluteMaxAlignment(); - setUpMachineAlignment(); - setUpDefaultAlignment(); - setUpPointerAlignment(); - setUpSignedChar(); - setUpCharSize(); - setUpWideCharSize(); - setUpShortSize(); - setUpIntegerSize(); - setUpLongSize(); - setUpLongLongSize(); - setUpFloatSize(); - setUpDoubleSize(); - setUpLongDoubleSize(); - - add(new GLabel("")); - add(new GLabel("")); - add(new GLabel("Absolute Max Alignment")); - add(absoluteMaxAlignComponent); - add(new GLabel("Machine Alignment")); - add(machineAlignComponent); - add(new GLabel("Default Alignment")); - add(defaultAlignComponent); - add(new GLabel("Default Pointer Alignment")); - add(pointerAlignComponent); - - add(new GLabel("")); - add(new GLabel("")); - add(new GLabel("Signed-Char:")); - add(charIsSignedCheckbox); - add(new GLabel("Char Size")); - add(charSizeComponent); - add(new GLabel("Wide-Char Size")); - add(wcharSizeComponent); - add(new GLabel("Short Size")); - add(shortSizeComponent); - add(new GLabel("Integer Size")); - add(integerSizeComponent); - add(new GLabel("Long Size")); - add(longSizeComponent); - add(new GLabel("LongLong Size")); - add(longLongSizeComponent); - add(new GLabel("Float Size")); - add(floatSizeComponent); - add(new GLabel("Double Size")); - add(doubleSizeComponent); - add(new GLabel("LongDouble Size")); - add(longDoubleSizeComponent); - add(new GLabel("")); - add(new GLabel("")); - } - - public void setOrganization(DataOrganizationImpl dataOrganization) { - this.dataOrganization = dataOrganization; - - int absoluteMaxAlignment = dataOrganization.getAbsoluteMaxAlignment(); - int machineAlignment = dataOrganization.getMachineAlignment(); - int defaultAlignment = dataOrganization.getDefaultAlignment(); - int defaultPointerAlignment = dataOrganization.getDefaultPointerAlignment(); - - int charSize = dataOrganization.getCharSize(); - int wcharSize = dataOrganization.getWideCharSize(); - int shortSize = dataOrganization.getShortSize(); - int integerSize = dataOrganization.getIntegerSize(); - int longSize = dataOrganization.getLongSize(); - int longLongSize = dataOrganization.getLongLongSize(); - int floatSize = dataOrganization.getFloatSize(); - int doubleSize = dataOrganization.getDoubleSize(); - int longDoubleSize = dataOrganization.getLongDoubleSize(); - - String maxAlignString = - (absoluteMaxAlignment == 0) ? "none" : Integer.toString(absoluteMaxAlignment); - absoluteMaxAlignComponent.setText(maxAlignString); - machineAlignComponent.setText(Integer.toString(machineAlignment)); - defaultAlignComponent.setText(Integer.toString(defaultAlignment)); - pointerAlignComponent.setText(Integer.toString(defaultPointerAlignment)); - - charSizeComponent.setText(Integer.toString(charSize)); - wcharSizeComponent.setText(Integer.toString(wcharSize)); - shortSizeComponent.setText(Integer.toString(shortSize)); - integerSizeComponent.setText(Integer.toString(integerSize)); - longSizeComponent.setText(Integer.toString(longSize)); - longLongSizeComponent.setText(Integer.toString(longLongSize)); - floatSizeComponent.setText(Integer.toString(floatSize)); - doubleSizeComponent.setText(Integer.toString(doubleSize)); - longDoubleSizeComponent.setText(Integer.toString(longDoubleSize)); - } - - private void setUpSignedChar() { - charIsSignedCheckbox = new GCheckBox(); - charIsSignedCheckbox.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - updateSignedChar(); - } - }); - } - - private void setUpCharSize() { - charSizeComponent = new JTextField(3); - charSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedCharSize(); - } - }); - charSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedCharSize(); - } - }); - } - - private void setUpWideCharSize() { - wcharSizeComponent = new JTextField(3); - wcharSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedWideCharSize(); - } - }); - wcharSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedWideCharSize(); - } - }); - } - - private void setUpShortSize() { - shortSizeComponent = new JTextField(3); - shortSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedShortSize(); - } - }); - shortSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedShortSize(); - } - }); - } - - private void setUpIntegerSize() { - integerSizeComponent = new JTextField(3); - integerSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedIntegerSize(); - } - }); - integerSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedIntegerSize(); - } - }); - } - - private void setUpLongSize() { - longSizeComponent = new JTextField(3); - longSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedLongSize(); - } - }); - longSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedLongSize(); - } - }); - } - - private void setUpLongLongSize() { - longLongSizeComponent = new JTextField(3); - longLongSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedLongLongSize(); - } - }); - longLongSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedLongLongSize(); - } - }); - } - - private void setUpFloatSize() { - floatSizeComponent = new JTextField(3); - floatSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedFloatSize(); - } - }); - floatSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedFloatSize(); - } - }); - } - - private void setUpDoubleSize() { - doubleSizeComponent = new JTextField(3); - doubleSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedDoubleSize(); - } - }); - doubleSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedDoubleSize(); - } - }); - } - - private void setUpLongDoubleSize() { - longDoubleSizeComponent = new JTextField(3); - longDoubleSizeComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedLongDoubleSize(); - } - }); - longDoubleSizeComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedLongDoubleSize(); - } - }); - } - - private void setUpAbsoluteMaxAlignment() { - absoluteMaxAlignComponent = new JTextField(3); - absoluteMaxAlignComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedAbsoluteMaxAlignment(); - } - }); - absoluteMaxAlignComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedAbsoluteMaxAlignment(); - } - }); - } - - private void setUpMachineAlignment() { - machineAlignComponent = new JTextField(3); - machineAlignComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedMachineAlignment(); - } - }); - machineAlignComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedMachineAlignment(); - } - }); - } - - private void setUpDefaultAlignment() { - defaultAlignComponent = new JTextField(3); - defaultAlignComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedDefaultAlignment(); - } - }); - defaultAlignComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedDefaultAlignment(); - } - }); - } - - private void setUpPointerAlignment() { - pointerAlignComponent = new JTextField(3); - pointerAlignComponent.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updatedDefaultPointerAlignment(); - } - }); - pointerAlignComponent.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - // TODO - } - - @Override - public void focusLost(FocusEvent e) { - updatedDefaultPointerAlignment(); - } - }); - } - - protected void updateSignedChar() { - boolean isSigned = charIsSignedCheckbox.isSelected(); - dataOrganization.setCharIsSigned(isSigned); - } - - protected void updatedCharSize() { - int charSize = Integer.decode(charSizeComponent.getText()).intValue(); - dataOrganization.setCharSize(charSize); - } - - protected void updatedWideCharSize() { - int wcharSize = Integer.decode(wcharSizeComponent.getText()).intValue(); - dataOrganization.setWideCharSize(wcharSize); - } - - protected void updatedShortSize() { - int shortSize = Integer.decode(shortSizeComponent.getText()).intValue(); - dataOrganization.setShortSize(shortSize); - } - - protected void updatedIntegerSize() { - int integerSize = Integer.decode(integerSizeComponent.getText()).intValue(); - dataOrganization.setIntegerSize(integerSize); - } - - protected void updatedLongSize() { - int longSize = Integer.decode(longSizeComponent.getText()).intValue(); - dataOrganization.setLongSize(longSize); - } - - protected void updatedLongLongSize() { - int longLongSize = Integer.decode(longLongSizeComponent.getText()).intValue(); - dataOrganization.setLongLongSize(longLongSize); - } - - protected void updatedFloatSize() { - int floatSize = Integer.decode(floatSizeComponent.getText()).intValue(); - dataOrganization.setFloatSize(floatSize); - } - - protected void updatedDoubleSize() { - int doubleSize = Integer.decode(doubleSizeComponent.getText()).intValue(); - dataOrganization.setDoubleSize(doubleSize); - } - - protected void updatedLongDoubleSize() { - int longDoubleSize = Integer.decode(longDoubleSizeComponent.getText()).intValue(); - dataOrganization.setLongDoubleSize(longDoubleSize); - } - - protected void updatedAbsoluteMaxAlignment() { - String maxAlignString = absoluteMaxAlignComponent.getText().toLowerCase(); - int absoluteMax = - ("none".equals(maxAlignString)) ? 0 : Integer.decode(maxAlignString).intValue(); - dataOrganization.setAbsoluteMaxAlignment(absoluteMax); - } - - protected void updatedMachineAlignment() { - int machineAlignment = Integer.decode(machineAlignComponent.getText()).intValue(); - dataOrganization.setMachineAlignment(machineAlignment); - } - - protected void updatedDefaultAlignment() { - int defaultAlignment = Integer.decode(defaultAlignComponent.getText()).intValue(); - dataOrganization.setDefaultAlignment(defaultAlignment); - } - - protected void updatedDefaultPointerAlignment() { - int defaultPointerAlignment = Integer.decode(pointerAlignComponent.getText()).intValue(); - dataOrganization.setDefaultPointerAlignment(defaultPointerAlignment); - } - -} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/SizeAlignmentPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/SizeAlignmentPanel.java deleted file mode 100644 index 6efc835b38..0000000000 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/SizeAlignmentPanel.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.datamgr; - -import java.awt.BorderLayout; -import java.awt.Dimension; - -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.event.TableModelListener; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableModel; - -import ghidra.program.model.data.DataOrganizationImpl; -import ghidra.util.Msg; -import ghidra.util.exception.NoValueException; -import ghidra.util.table.GhidraTable; - -public class SizeAlignmentPanel extends JPanel { - - GhidraTable table; - DataOrganizationImpl dataOrganization; - - public SizeAlignmentPanel() { - super(new BorderLayout()); - TableModel tableModel = new SizeAlignmentTableModel(); - table = new GhidraTable(tableModel); - table.setAutoEditEnabled(true); - JScrollPane sp = new JScrollPane(table); - table.setPreferredScrollableViewportSize(new Dimension(200, 80)); - add(sp, BorderLayout.CENTER); - } - - public void setOrganization(DataOrganizationImpl dataOrganization) { - this.dataOrganization = dataOrganization; - ((SizeAlignmentTableModel) table.getModel()).fireTableDataChanged(); - } - - class SizeAlignmentTableModel extends AbstractTableModel { - - private final String[] columnNames = new String[] { "Size", "Alignment" }; - private final int SIZE_COLUMN = 0; - private final int ALIGNMENT_COLUMN = 1; - - SizeAlignmentTableModel() { - super(); - } - - @Override - public void addTableModelListener(TableModelListener l) { - // TODO Auto-generated method stub - - } - - @Override - public Class> getColumnClass(int columnIndex) { - return Integer.class; - } - - @Override - public int getColumnCount() { - return columnNames.length; - } - - @Override - public String getColumnName(int columnIndex) { - return columnNames[columnIndex]; - } - - @Override - public int getRowCount() { - return dataOrganization.getSizeAlignmentCount() + 1; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - int[] sizes = dataOrganization.getSizes(); - if (rowIndex < sizes.length) { - int size = sizes[rowIndex]; - if (columnIndex == SIZE_COLUMN) { - return size; - } - else if (columnIndex == ALIGNMENT_COLUMN) { - try { - return dataOrganization.getSizeAlignment(size); - } - catch (NoValueException e) { - return null; - } - } - } - return null; - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - if (rowIndex == dataOrganization.getSizeAlignmentCount()) { - return columnIndex == SIZE_COLUMN; - } - return columnIndex == ALIGNMENT_COLUMN; - } - - @Override - public void removeTableModelListener(TableModelListener l) { - // TODO Auto-generated method stub - - } - - @Override - public void setValueAt(Object value, int rowIndex, int columnIndex) { - if (value == null) { - return; - } - int[] sizes = dataOrganization.getSizes(); - if (rowIndex < sizes.length) { - int alignment = ((Integer) value).intValue(); - int size = sizes[rowIndex]; - dataOrganization.setSizeAlignment(size, alignment); - } - if (rowIndex == sizes.length) { - int size = ((Integer) value).intValue(); - // Check that we don't already have this size. - try { - dataOrganization.getSizeAlignment(size); - setStatusMessage("An alignment is already defined for a size of " + size + "."); - return; - } - catch (NoValueException e) { - // Actually don't want to find a value so we can set one below. - } - int alignment = size; // Set the alignment to match the size initially. - dataOrganization.setSizeAlignment(size, alignment); - fireTableDataChanged(); - } - } - } - - public void setStatusMessage(String message) { - // TODO Change this to write to the status line in the dialog. - Msg.showError(this, this, "Invalid Input", message); - } - -} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreview.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreview.java index 89bec3f921..c53b584ed2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreview.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datapreview/DataTypePreview.java @@ -41,7 +41,8 @@ class DataTypePreview implements Preview { public String getPreview(Memory memory, Address addr) { try { MemBuffer mb = new DumbMemBufferImpl(memory, addr); - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, mb, MAX_PREVIEW_LENGTH); + DataTypeInstance dti = + DataTypeInstance.getDataTypeInstance(dt, mb, MAX_PREVIEW_LENGTH, false); if (dti == null) { return ""; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToDoubleAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToDoubleAction.java index 82545588e9..1bf6353fb6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToDoubleAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToDoubleAction.java @@ -42,7 +42,7 @@ public class ConvertToDoubleAction extends AbstractConvertAction { try { FloatFormat format = FloatFormatFactory.getFloatFormat(dataOrganization.getDoubleSize()); - return format.round(format.getHostFloat(s.getBigInteger())); + return format.round(format.decodeBigFloat(s.getBigInteger())); } catch (UnsupportedFloatFormatException e) { return null; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToFloatAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToFloatAction.java index 63121d40e7..068730c1db 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToFloatAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertToFloatAction.java @@ -41,7 +41,7 @@ public class ConvertToFloatAction extends AbstractConvertAction { DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization(); try { FloatFormat format = FloatFormatFactory.getFloatFormat(dataOrganization.getFloatSize()); - return format.round(format.getHostFloat(s.getBigInteger())); + return format.round(format.decodeBigFloat(s.getBigInteger())); } catch (UnsupportedFloatFormatException e) { return null; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/CreateArrayAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/CreateArrayAction.java index a4d65ce347..31c1adf85e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/CreateArrayAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/CreateArrayAction.java @@ -100,16 +100,19 @@ class CreateArrayAction extends ListingContextAction { Variable var = varLoc.getVariable(); if (var.isStackVariable()) { DataType dt = var.getDataType(); - int len = var.getLength(); - int defaultElements = plugin.getMaxStackVariableSize(fun, var); - if (defaultElements <= 0) { - defaultElements = 1; + if (dt.getLength() < 1) { + return; } - int n = getNumElements(dt, Integer.MAX_VALUE, defaultElements); + int availableLen = plugin.getMaxStackVariableSize(fun, var); + if (availableLen <= 0) { + availableLen = 1; + } + int maxElements = availableLen / var.getDataType().getAlignedLength(); + int n = getNumElements(dt, Integer.MAX_VALUE, maxElements); if (n == 0) { return; } - Array array = new ArrayDataType(dt, n, len); + Array array = new ArrayDataType(dt, n, -1); plugin.createData(array, context, true, true); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java index 9738c72714..229dc60db4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java @@ -22,6 +22,7 @@ import ghidra.app.util.cparser.C.ParseException; import ghidra.app.util.parser.FunctionSignatureParser; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.program.model.lang.*; import ghidra.program.model.listing.*; import ghidra.program.model.listing.Function.FunctionUpdateType; @@ -1206,6 +1207,7 @@ public class FunctionEditorModel { catch (InvalidInputException e) { // ignore } + setFunctionData(f); isInParsingMode = false; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/StorageAddressEditorDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/StorageAddressEditorDialog.java index ecb59ff7d9..d93e25a9bb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/StorageAddressEditorDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/StorageAddressEditorDialog.java @@ -33,6 +33,7 @@ import ghidra.app.util.datatype.DataTypeSelectionEditor; import ghidra.app.util.datatype.NavigationDirection; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.util.HelpLocation; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/stackeditor/StackEditorModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/stackeditor/StackEditorModel.java index d90d9c3c32..df158a4e1b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/stackeditor/StackEditorModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/stackeditor/StackEditorModel.java @@ -202,7 +202,7 @@ public class StackEditorModel extends CompositeEditorModel { dt = element.getDataType(); dtLen = dt.getLength(); return DataTypeInstance.getDataTypeInstance(dt, - (dtLen > 0) ? dtLen : element.getLength()); + (dtLen > 0) ? dtLen : element.getLength(), true); case NAME: String fieldName = getFieldNameAtRow(rowIndex, (StackFrameDataType) viewComposite); if (fieldName == null) { @@ -1127,7 +1127,7 @@ public class StackEditorModel extends CompositeEditorModel { OffsetPairs offsetSelection = getRelOffsetSelection(); int transID = startTransaction("Apply Data Type \"" + dt.getName() + "\""); try { - fieldEdited(DataTypeInstance.getDataTypeInstance(dt, dtLength), index, + fieldEdited(DataTypeInstance.getDataTypeInstance(dt, dtLength, true), index, getDataTypeColumn()); setRelOffsetSelection(offsetSelection); } @@ -1157,7 +1157,7 @@ public class StackEditorModel extends CompositeEditorModel { if (max == Integer.MAX_VALUE) { return Integer.MAX_VALUE; } - return max / dtc.getLength(); + return max / dtc.getDataType().getAlignedLength(); } @Override @@ -1320,7 +1320,7 @@ public class StackEditorModel extends CompositeEditorModel { dtName = dt.getDisplayName(); if (dtString.equals(dtName)) { return DataTypeInstance.getDataTypeInstance(element.getDataType(), - element.getLength()); + element.getLength(), true); } } @@ -1346,7 +1346,7 @@ public class StackEditorModel extends CompositeEditorModel { if (maxLength > 0 && newLength > maxLength) { throw new UsrException(newDt.getDisplayName() + " doesn't fit."); } - return DataTypeInstance.getDataTypeInstance(newDt, newLength); + return DataTypeInstance.getDataTypeInstance(newDt, newLength, true); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeManager.java index b2437cf07c..c1cb3cb9be 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFDataTypeManager.java @@ -25,6 +25,7 @@ import ghidra.app.util.bin.format.dwarf4.encoding.*; import ghidra.app.util.bin.format.dwarf4.expression.DWARFExpressionException; import ghidra.app.util.bin.format.dwarf4.next.DWARFDataTypeImporter.DWARFDataType; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.program.model.lang.CompilerSpec; import ghidra.program.model.listing.Program; import ghidra.util.Msg; @@ -381,7 +382,7 @@ public class DWARFDataTypeManager { String mangledName = null; if (name != null) { dt = baseDataTypes.get(name); - if (dt != null && dt.getLength() == dwarfSize && + if (dt != null && dt.getAlignedLength() == dwarfSize && isEncodingCompatible(dwarfEncoding, dt)) { return dt; } @@ -394,6 +395,9 @@ public class DWARFDataTypeManager { dt = switch (dwarfEncoding) { case DWARFEncoding.DW_ATE_address -> baseDataTypeVoid; // TODO: Check if bytesize != 0 - may want to make a void pointer case DWARFEncoding.DW_ATE_boolean -> dwarfSize == 1 ? baseDataTypeBool : null; + // TODO: Float lookup by length must use "raw" encoding size since "aligned" lengths + // may be duplicated across different float types. Lookup by name is preferred. + // May need to add name lookup capability to AbstractFloatDataType case DWARFEncoding.DW_ATE_float -> AbstractFloatDataType.getFloatDataType(dwarfSize, getCorrectDTMForFixedLengthTypes(name, dwarfSize)); case DWARFEncoding.DW_ATE_signed -> AbstractIntegerDataType.getSignedDataType(dwarfSize, @@ -426,6 +430,7 @@ public class DWARFDataTypeManager { return dt; } + private DataTypeManager getCorrectDTMForFixedLengthTypes(String name, int dwarfSize) { // If the requested name of the base type appears to have a bitsize string // embedded in it, this chunk of code will switch between using the normal DTM diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliAbstractSig.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliAbstractSig.java index 9897ffc86a..a0d1d486a6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliAbstractSig.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliAbstractSig.java @@ -25,6 +25,8 @@ import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata; import ghidra.app.util.bin.format.pe.cli.tables.*; import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexTypeDefOrRef; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.Float32DataType; +import ghidra.program.model.data.floats.Float64DataType; import ghidra.util.exception.InvalidInputException; public abstract class CliAbstractSig extends CliBlob implements CliRepresentable { @@ -139,9 +141,9 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable return UnsignedIntegerDataType.dataType; case ELEMENT_TYPE_R4: - return Float4DataType.dataType; + return Float32DataType.dataType; case ELEMENT_TYPE_R8: - return Float8DataType.dataType; + return Float64DataType.dataType; case ELEMENT_TYPE_I8: return LongLongDataType.dataType; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java index f27e125b47..a28a9fad82 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java @@ -32,6 +32,8 @@ import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodDef.CliMethodDefRo import ghidra.app.util.bin.format.pe.cli.tables.CliTypeTable; import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.Float32DataType; +import ghidra.program.model.data.floats.Float64DataType; import ghidra.util.Msg; import ghidra.util.exception.InvalidInputException; @@ -410,12 +412,12 @@ public class CliBlobCustomAttrib extends CliBlob { case ELEMENT_TYPE_R4: addFixedArg(processFixedArgs, baseTypeCode, - reader.readNextByteArray(Float4DataType.dataType.getLength())); + reader.readNextByteArray(Float32DataType.dataType.getLength())); break; case ELEMENT_TYPE_R8: addFixedArg(processFixedArgs, baseTypeCode, - reader.readNextByteArray(Float8DataType.dataType.getLength())); + reader.readNextByteArray(Float64DataType.dataType.getLength())); break; case ELEMENT_TYPE_STRING: diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/microsoft/RTTI0DataType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/microsoft/RTTI0DataType.java index 23b498a8e0..d0f1511ba7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/microsoft/RTTI0DataType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/microsoft/RTTI0DataType.java @@ -15,8 +15,7 @@ */ package ghidra.app.util.datatype.microsoft; -import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.getAbsoluteAddress; -import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.is64Bit; +import static ghidra.app.util.datatype.microsoft.MSDataTypeUtils.*; import ghidra.docking.settings.Settings; import ghidra.docking.settings.SettingsImpl; @@ -111,7 +110,7 @@ public class RTTI0DataType extends RTTIDataType { Address nameAddress = start.add(nameOffset); MemoryBufferImpl nameBuf = new MemoryBufferImpl(buf.getMemory(), nameAddress, 1024); DataTypeInstance dti = - DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf); + DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf, false); if (dti != null) { comps[2] = new ReadOnlyDataTypeComponent(dti.getDataType(), this, dti.getLength(), 2, @@ -178,7 +177,8 @@ public class RTTI0DataType extends RTTIDataType { WrappedMemBuffer nameBuf = null; try { nameBuf = new WrappedMemBuffer(buf, getNameOffset(buf.getMemory().getProgram())); - dti = DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf); + dti = DataTypeInstance.getDataTypeInstance(new TerminatedStringDataType(), nameBuf, + false); } catch (AddressOutOfBoundsException e) { // ignore diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledDataType.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledDataType.java index 4be03fb360..7c389cda9a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledDataType.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledDataType.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.StringUtils; import ghidra.program.database.data.DataTypeUtilities; import ghidra.program.model.data.*; import ghidra.program.model.data.Enum; +import ghidra.program.model.data.floats.Float128DataType; import ghidra.program.model.symbol.Namespace; /** @@ -283,7 +284,7 @@ public class DemangledDataType extends DemangledType { dt = FloatDataType.dataType; } else if (FLOAT128.equals(name)) { - dt = new TypedefDataType(FLOAT128, Float16DataType.dataType); + dt = new TypedefDataType(FLOAT128, Float128DataType.dataType); } else if (DOUBLE.equals(name)) { dt = DoubleDataType.dataType; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/DefinedDataXmlMgr.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/DefinedDataXmlMgr.java index 62dc99923e..f12a983a9b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/DefinedDataXmlMgr.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/DefinedDataXmlMgr.java @@ -149,7 +149,7 @@ class DefinedDataXmlMgr { private void clearExistingData(Address addr, int size, DataType dt, Listing listing) { DumbMemBufferImpl buf = new DumbMemBufferImpl(program.getMemory(), addr); - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, buf, size); + DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dt, buf, size, false); if (dti != null) { boolean doClear = false; Address maxAddr = addr.add(dti.getLength() - 1); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/ProcessorEmulatorTestAdapter.java b/Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/ProcessorEmulatorTestAdapter.java index f26e95e0d4..f3ed945cdb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/ProcessorEmulatorTestAdapter.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/ProcessorEmulatorTestAdapter.java @@ -784,7 +784,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E false) : LittleEndianDataConverter.INSTANCE.getBigInteger(bytes, index, elementSize, false); - BigDecimal val = ff.round(ff.getHostFloat(encoding)); + BigDecimal val = ff.round(ff.decodeBigFloat(encoding)); return val.toString(); } } @@ -879,7 +879,7 @@ public abstract class ProcessorEmulatorTestAdapter extends TestCase implements E if (reg != null && floatRegSet.contains(reg)) { FloatFormat floatFormat = FloatFormatFactory.getFloatFormat(size); BigDecimal hostFloat = - floatFormat.round(floatFormat.getHostFloat(new BigInteger(1, values))); + floatFormat.round(floatFormat.decodeBigFloat(new BigInteger(1, values))); floatStr = " (" + hostFloat.toString() + ")"; } 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 575f6e7370..9bfa4df093 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 @@ -22,7 +22,6 @@ import static org.junit.Assert.*; import org.junit.*; -import ghidra.app.events.ProgramActivatedPluginEvent; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin; import ghidra.app.plugin.core.datapreview.DataTypePreviewPlugin.DTPPTableModel; @@ -174,6 +173,7 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe // integerSize = 4; // longSize = 4; // defaultAlignment = 1; + // alignment per size: 2->2, 4->4, 8->4 plugin.addDataType(IntegerDataType.dataType); plugin.addDataType(LongDataType.dataType); @@ -190,12 +190,11 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe assertEquals(6, model.getRowCount()); Program program = buildProgram(); - DataOrganizationImpl dataOrganization = - (DataOrganizationImpl) program.getDataTypeManager().getDataOrganization(); - + (DataOrganizationImpl) program.getCompilerSpec().getDataOrganization(); dataOrganization.setLongSize(8); + // Open program in tool and goto tested memory location env.open(program); gotoService.goTo(addr(program, 0x100df26)); @@ -210,19 +209,23 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe 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 - // deactivate program - plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", null)); - waitForPostedSwingRunnables(); + env.close(program); + // Re-create program with mutated data-organization to simulate shift to 3-byte aligned types // NOTE: Altering data organization on-the-fly is not supported - dataOrganization.setDefaultAlignment(2); + + // alignment map should jive with 3-byte mutliple primitive type sizes + dataOrganization.clearSizeAlignmentMap(); + dataOrganization.setSizeAlignment(1, 1); + dataOrganization.setSizeAlignment(3, 3); + dataOrganization.setSizeAlignment(6, 6); dataOrganization.setShortSize(3); dataOrganization.setIntegerSize(3); dataOrganization.setLongSize(6); - // activate program - plugin.getTool().firePluginEvent(new ProgramActivatedPluginEvent("Test", program)); - waitForPostedSwingRunnables(); + // Open program in tool and goto tested memory location + program = buildProgram(); + env.open(program); gotoService.goTo(addr(program, 0x100df26)); @@ -231,8 +234,8 @@ public class DataTypePreviewPluginTest extends AbstractGhidraHeadedIntegrationTe assertEquals("680054h", model.getValueAt(2, DTPPTableModel.PREVIEW_COL));// 3-byte short assertEquals("680054h", model.getValueAt(3, DTPPTableModel.PREVIEW_COL));// 3-byte int at offset 0 - assertEquals("4D00200065h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 6-byte long at offset 4 - assertEquals("720061h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 3-byte short at offset 10 + assertEquals("61004D0020h", model.getValueAt(4, DTPPTableModel.PREVIEW_COL));// 6-byte long at offset 6 + assertEquals("670072h", model.getValueAt(5, DTPPTableModel.PREVIEW_COL));// 3-byte short at offset 12 } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquatePlugin1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquatePlugin1Test.java index 537921988e..75cc258037 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquatePlugin1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquatePlugin1Test.java @@ -863,7 +863,7 @@ public class EquatePlugin1Test extends AbstractGhidraHeadedIntegrationTest { } else if (name.indexOf("Float") >= 0) { assertTrue(popupPath[1].startsWith("Float")); - assertTrue(popupPath[1].endsWith(" 5.605194E-45")); + assertTrue(popupPath[1].endsWith(" 5.6051939E-45")); } else { fail("Unhandled Convert item: " + name); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptRealProgramTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptRealProgramTest.java index ddb316cdcd..f37b09f12e 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptRealProgramTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/script/GhidraScriptRealProgramTest.java @@ -23,6 +23,7 @@ import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin; import ghidra.app.plugin.core.script.GhidraScriptMgrPlugin; import ghidra.framework.plugintool.PluginTool; +import ghidra.pcode.floatformat.BigFloat; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; import ghidra.program.model.listing.*; @@ -400,13 +401,13 @@ public class GhidraScriptRealProgramTest extends AbstractGhidraHeadedIntegration address = script.toAddr(0x010085a7); data = script.createFloat(address); assertNotNull(data); - assertEquals(-1.4682312f, data.getValue()); + assertEquals("-1.468231", ((BigFloat) data.getValue()).toString()); script.clearListing(address); address = script.toAddr(0x010085a9); data = script.createDouble(address); assertNotNull(data); - assertEquals(-8.373196719664668E298, data.getValue()); + assertEquals("-8.37319671966467E+298", ((BigFloat) data.getValue()).toString()); script.clearListing(address); } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertDoubleAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertDoubleAction.java index a894f983d6..64fb76abbd 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertDoubleAction.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertDoubleAction.java @@ -64,7 +64,7 @@ public class ConvertDoubleAction extends ConvertConstantAction { private static BigDecimal value(int size, Scalar s) { try { FloatFormat format = FloatFormatFactory.getFloatFormat(size); - return format.round(format.getHostFloat(s.getBigInteger())); + return format.round(format.decodeBigFloat(s.getBigInteger())); } catch (UnsupportedFloatFormatException e) { return null; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertFloatAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertFloatAction.java index ba33fb2de9..3aed950432 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertFloatAction.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/ConvertFloatAction.java @@ -64,7 +64,7 @@ public class ConvertFloatAction extends ConvertConstantAction { private static BigDecimal value(int size, Scalar s) { try { FloatFormat format = FloatFormatFactory.getFloatFormat(size); - return format.round(format.getHostFloat(s.getBigInteger())); + return format.round(format.decodeBigFloat(s.getBigInteger())); } catch (UnsupportedFloatFormatException e) { return null; diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb/PdbParser.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb/PdbParser.java index 397fb2fb03..e153a7bb67 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb/PdbParser.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb/PdbParser.java @@ -794,7 +794,7 @@ public class PdbParser { void createData(Address address, DataType dataType, MessageLog log) { DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), address); - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer); + DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer, false); if (dti == null) { log.appendMsg("PDB", "Failed to apply datatype " + dataType.getName() + " at " + address); diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DataSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DataSymbolApplier.java index 6e6dd95ee8..f6fc4d1b2e 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DataSymbolApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/DataSymbolApplier.java @@ -115,7 +115,7 @@ public class DataSymbolApplier extends MsSymbolApplier { //TODO: might want to do an ApplyDatatypeCmd here!!! DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(applicator.getProgram().getMemory(), address); - DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer); + DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(dataType, memBuffer, false); if (dti == null) { applicator.appendLogMsg( "Error: Failed to apply datatype " + dataType.getName() + " at " + address); diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbPrimitiveTypeApplicator.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbPrimitiveTypeApplicator.java index f391b82841..afedefb47d 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbPrimitiveTypeApplicator.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbPrimitiveTypeApplicator.java @@ -20,6 +20,7 @@ import java.util.*; import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog; import ghidra.app.util.bin.format.pdb2.pdbreader.type.PrimitiveMsType; import ghidra.program.model.data.*; +import ghidra.program.model.data.floats.AbstractFloatDataType; import ghidra.util.exception.AssertException; /** @@ -516,21 +517,24 @@ public class PdbPrimitiveTypeApplicator { return getRealType(16, "float128"); } - /* + /** * First get type from "other" list, which are typedefs to underlying primitives. If it does * not exist, then find the proper underlying primitive, create the typedef, and cache this * newly minted (typedef) unique primitive type. + * @param rawSize "raw" encoding size in bytes + * @param name assigned type name */ - private DataType getRealType(int size, String name) { + private DataType getRealType(int rawSize, String name) { DataType dataType = otherPrimitives.get(name); if (dataType != null) { return dataType; } - dataType = floatGhidraPrimitives.get(size); + dataType = floatGhidraPrimitives.get(rawSize); DataType resolved; if (dataType == null) { - resolved = resolve(AbstractFloatDataType.getFloatDataType(size, getDataTypeManager())); - floatGhidraPrimitives.put(size, resolved); + resolved = + resolve(AbstractFloatDataType.getFloatDataType(rawSize, getDataTypeManager())); + floatGhidraPrimitives.put(rawSize, resolved); if (resolved instanceof Undefined) { // Not a real type implemented in Ghidra. DataType type = createTypedef(name, resolved); resolved = resolve(type); diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAbsTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAbsTest.java index bf1a407cb2..b3f32c9623 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAbsTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAbsTest.java @@ -38,23 +38,23 @@ public class OpBehaviorFloatAbsTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long result = op.evaluateUnary(8, 8, ff.opAbs(a)); - Assert.assertEquals(2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.5); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -66,23 +66,23 @@ public class OpBehaviorFloatAbsTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.5d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAddTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAddTest.java index 4a7f4267c1..6daa0bfbd5 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAddTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatAddTest.java @@ -39,32 +39,32 @@ public class OpBehaviorFloatAddTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(1.234); long b = ff.getEncoding(1.123); long result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123 - Assert.assertEquals(2.357, ff.getHostFloat(result), 0); + Assert.assertEquals(2.357, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-1.123); result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123 - Assert.assertEquals(0d, ff.getHostFloat(result), 0); + Assert.assertEquals(0d, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123 - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123 - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); b = ff.getEncoding(1.123); result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123 - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -77,32 +77,32 @@ public class OpBehaviorFloatAddTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(1.234d)); BigInteger b = ff.getEncoding(ff.getBigFloat(1.123d)); BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.234 + 1.123 - Assert.assertEquals(ff.getBigFloat(2.357), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.357), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-1.123d)); result = op.evaluateBinary(8, 8, a, b);// -1.123 + 1.123 - Assert.assertEquals(ff.getBigZero(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigZero(false), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigInfinity(false)); result = op.evaluateBinary(8, 8, a, b);// +INFINITY + 1.123 - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + 1.123 - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); b = ff.getBigInfinityEncoding(true); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + -INFINITY - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); b = ff.getEncoding(ff.getBigInfinity(false)); result = op.evaluateBinary(8, 8, a, b);// -INFINITY + +INFINITY - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); b = ff.getEncoding(ff.getBigFloat(1.123d)); result = op.evaluateBinary(8, 8, a, b);// NaN + 1.123 - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatCeilTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatCeilTest.java index 119c360acc..29cd37cc61 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatCeilTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatCeilTest.java @@ -38,23 +38,23 @@ public class OpBehaviorFloatCeilTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long result = ff.opCeil(a); - Assert.assertEquals(3.0, ff.getHostFloat(result), 0); + Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.5); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -66,23 +66,23 @@ public class OpBehaviorFloatCeilTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.5d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatDivTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatDivTest.java index 76d484ee4e..85649639e4 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatDivTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatDivTest.java @@ -39,19 +39,19 @@ public class OpBehaviorFloatDivTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(3.75); long b = ff.getEncoding(1.5); long result = ff.opDiv(a, b); - Assert.assertEquals(2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0); b = ff.getEncoding(0); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-3.75); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.NaN); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -64,19 +64,19 @@ public class OpBehaviorFloatDivTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(3.75d)); BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d)); BigInteger result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result)); b = ff.getBigZeroEncoding(false); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-3.75d)); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); b = ff.getBigNaNEncoding(false); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloat2FloatTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloat2FloatTest.java index b67798e0f3..1ecd39a17d 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloat2FloatTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloat2FloatTest.java @@ -39,23 +39,23 @@ public class OpBehaviorFloatFloat2FloatTest extends AbstractOpBehaviorTest { long a = ff4.getEncoding(1.75); long result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(1.75, ff8.getHostFloat(result), 0); + Assert.assertEquals(1.75, ff8.decodeHostFloat(result), 0); a = ff4.getEncoding(-1.75); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(-1.75, ff8.getHostFloat(result), 0); + Assert.assertEquals(-1.75, ff8.decodeHostFloat(result), 0); a = ff4.getEncoding(Float.POSITIVE_INFINITY); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff8.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff8.decodeHostFloat(result), 0); a = ff4.getEncoding(Float.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff8.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff8.decodeHostFloat(result), 0); a = ff4.getEncoding(Float.NaN); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(Double.NaN, ff8.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff8.decodeHostFloat(result), 0); } @Test @@ -68,23 +68,23 @@ public class OpBehaviorFloatFloat2FloatTest extends AbstractOpBehaviorTest { BigInteger a = ff4.getEncoding(ff4.getBigFloat(1.75d)); BigInteger result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(ff8.getBigFloat(1.75d), ff8.getHostFloat(result)); + Assert.assertEquals(ff8.getBigFloat(1.75d), ff8.decodeBigFloat(result)); a = ff4.getEncoding(ff4.getBigFloat(-1.75d)); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(ff8.getBigFloat(-1.75d), ff8.getHostFloat(result)); + Assert.assertEquals(ff8.getBigFloat(-1.75d), ff8.decodeBigFloat(result)); a = ff4.getEncoding(ff4.getBigInfinity(false)); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(ff8.getBigInfinity(false), ff8.getHostFloat(result)); + Assert.assertEquals(ff8.getBigInfinity(false), ff8.decodeBigFloat(result)); a = ff4.getEncoding(ff4.getBigInfinity(true)); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(ff8.getBigInfinity(true), ff8.getHostFloat(result)); + Assert.assertEquals(ff8.getBigInfinity(true), ff8.decodeBigFloat(result)); a = ff4.getEncoding(ff4.getBigNaN(false)); result = op.evaluateUnary(8, 4, a); - Assert.assertEquals(ff8.getBigNaN(false), ff8.getHostFloat(result)); + Assert.assertEquals(ff8.getBigNaN(false), ff8.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloorTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloorTest.java index 8841e3fd45..1d13db78d0 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloorTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatFloorTest.java @@ -38,27 +38,27 @@ public class OpBehaviorFloatFloorTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.0); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.5); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-3.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-3.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -70,27 +70,27 @@ public class OpBehaviorFloatFloorTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.0d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.5d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-3.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-3.0d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatInt2FloatTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatInt2FloatTest.java index bb93e7bcca..3d506b61f6 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatInt2FloatTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatInt2FloatTest.java @@ -41,19 +41,19 @@ public class OpBehaviorFloatInt2FloatTest extends AbstractOpBehaviorTest { long result = op.evaluateUnary(4, 4, 2); Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used - Assert.assertEquals(2.0d, ff.getHostFloat(result), 0); + Assert.assertEquals(2.0d, ff.decodeHostFloat(result), 0); result = op.evaluateUnary(4, 4, -2); Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used - Assert.assertEquals(-2.0d, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.0d, ff.decodeHostFloat(result), 0); result = op.evaluateUnary(4, 4, 0); Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used - Assert.assertEquals(0d, ff.getHostFloat(result), 0); + Assert.assertEquals(0d, ff.decodeHostFloat(result), 0); result = op.evaluateUnary(4, 4, 0x0ffffffffL); Assert.assertEquals(0, result & 0xffffffff00000000L);// verify that only 4-bytes are used - Assert.assertEquals(-1.0d, ff.getHostFloat(result), 0); + Assert.assertEquals(-1.0d, ff.decodeHostFloat(result), 0); } @Test @@ -67,20 +67,20 @@ public class OpBehaviorFloatInt2FloatTest extends AbstractOpBehaviorTest { BigInteger result = op.evaluateUnary(4, 4, BigInteger.valueOf(2)); assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used - Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result)); result = op.evaluateUnary(4, 4, BigInteger.valueOf(-2)); assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used - Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result)); result = op.evaluateUnary(4, 4, BigInteger.ZERO); assertTrue(result.compareTo(limit) < 0);// verify that only 4-bytes are used - Assert.assertEquals(ff.getBigZero(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigZero(false), ff.decodeBigFloat(result)); BigInteger NEG_ONE = Utils.bytesToBigInteger( new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, 4, false, false); result = op.evaluateUnary(4, 4, NEG_ONE); - Assert.assertEquals(ff.getBigFloat(-1.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-1.0d), ff.decodeBigFloat(result)); } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatMultTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatMultTest.java index fb83fa3f8a..3d7a4f3022 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatMultTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatMultTest.java @@ -39,19 +39,19 @@ public class OpBehaviorFloatMultTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long b = ff.getEncoding(1.5); long result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(3.75, ff.getHostFloat(result), 0); + Assert.assertEquals(3.75, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.NaN); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -64,19 +64,19 @@ public class OpBehaviorFloatMultTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger b = ff.getEncoding(ff.getBigFloat(1.5d)); BigInteger result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigFloat(3.75d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(3.75d), ff.decodeBigFloat(result)); b = ff.getBigInfinityEncoding(false); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); b = ff.getBigNaNEncoding(false); result = op.evaluateBinary(8, 8, a, b); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatNegTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatNegTest.java index 257507e6eb..c2143f7dde 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatNegTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatNegTest.java @@ -38,23 +38,23 @@ public class OpBehaviorFloatNegTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.5, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.5); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(2.5, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -66,23 +66,23 @@ public class OpBehaviorFloatNegTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.5d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.5d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.5d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatRoundTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatRoundTest.java index 37eaab782a..90ef4cdfbd 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatRoundTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatRoundTest.java @@ -38,39 +38,39 @@ public class OpBehaviorFloatRoundTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(2.5); long result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(3.0, ff.getHostFloat(result), 0); + Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(2.25); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(2.75); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(3.0, ff.getHostFloat(result), 0); + Assert.assertEquals(3.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.5); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.25); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-2.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-2.75); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(-3.0, ff.getHostFloat(result), 0); + Assert.assertEquals(-3.0, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -82,39 +82,39 @@ public class OpBehaviorFloatRoundTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(2.5d)); BigInteger result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(2.25d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(2.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(2.75d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(3.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(3.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.5d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.25d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-2.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.0d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-2.75d)); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigFloat(-3.0d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-3.0d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); result = op.evaluateUnary(8, 8, a); - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSqrtTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSqrtTest.java index 2836a0e4bf..d30c91ef47 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSqrtTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSqrtTest.java @@ -37,7 +37,7 @@ public class OpBehaviorFloatSqrtTest extends AbstractOpBehaviorTest { long longbits = ff.getEncoding(2.0); longbits = op.evaluateUnary(8, 8, longbits); - double d = ff.getHostFloat(longbits); + double d = ff.decodeHostFloat(longbits); Assert.assertEquals("1.414213562373095", Double.toString(d).substring(0, 17)); } @@ -52,7 +52,7 @@ public class OpBehaviorFloatSqrtTest extends AbstractOpBehaviorTest { BigFloat big = ff.getBigFloat(2.0); BigInteger encoding = ff.getEncoding(big); encoding = op.evaluateUnary(8, 8, encoding); - BigFloat result = ff.getHostFloat(encoding); + BigFloat result = ff.decodeBigFloat(encoding); Assert.assertEquals("1.414213562373095", ff.round(result).toString()); } diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSubTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSubTest.java index f0966507c6..b9dee62599 100644 --- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSubTest.java +++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/opbehavior/OpBehaviorFloatSubTest.java @@ -39,32 +39,32 @@ public class OpBehaviorFloatSubTest extends AbstractOpBehaviorTest { long a = ff.getEncoding(1.5); long b = ff.getEncoding(1.25); long result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25 - Assert.assertEquals(0.25, ff.getHostFloat(result), 0); + Assert.assertEquals(0.25, ff.decodeHostFloat(result), 0); a = ff.getEncoding(-1.25); result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25 - Assert.assertEquals(-2.5, ff.getHostFloat(result), 0); + Assert.assertEquals(-2.5, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25 - Assert.assertEquals(Double.POSITIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.POSITIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25 - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.NEGATIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); b = ff.getEncoding(Double.POSITIVE_INFINITY); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY - Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NEGATIVE_INFINITY, ff.decodeHostFloat(result), 0); a = ff.getEncoding(Double.NaN); b = ff.getEncoding(1.25); result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25 - Assert.assertEquals(Double.NaN, ff.getHostFloat(result), 0); + Assert.assertEquals(Double.NaN, ff.decodeHostFloat(result), 0); } @Test @@ -77,32 +77,32 @@ public class OpBehaviorFloatSubTest extends AbstractOpBehaviorTest { BigInteger a = ff.getEncoding(ff.getBigFloat(1.5d)); BigInteger b = ff.getEncoding(ff.getBigFloat(1.25d)); BigInteger result = op.evaluateBinary(8, 8, a, b);// 1.5 - 1.25 - Assert.assertEquals(ff.getBigFloat(0.25d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(0.25d), ff.decodeBigFloat(result)); a = ff.getEncoding(ff.getBigFloat(-1.25d)); result = op.evaluateBinary(8, 8, a, b);// -1.25 - 1.25 - Assert.assertEquals(ff.getBigFloat(-2.5d), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigFloat(-2.5d), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(false); result = op.evaluateBinary(8, 8, a, b);// +INFINITY - 1.25 - Assert.assertEquals(ff.getBigInfinity(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(false), ff.decodeBigFloat(result)); a = ff.getBigInfinityEncoding(true); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - 1.25 - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); b = ff.getBigInfinityEncoding(true); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - -INFINITY - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); b = ff.getBigInfinityEncoding(false); result = op.evaluateBinary(8, 8, a, b);// -INFINITY - +INFINITY - Assert.assertEquals(ff.getBigInfinity(true), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigInfinity(true), ff.decodeBigFloat(result)); a = ff.getBigNaNEncoding(false); b = ff.getEncoding(ff.getBigFloat(1.25d)); result = op.evaluateBinary(8, 8, a, b);// NaN - 1.25 - Assert.assertEquals(ff.getBigNaN(false), ff.getHostFloat(result)); + Assert.assertEquals(ff.getBigNaN(false), ff.decodeBigFloat(result)); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramProviderContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramProviderContext.java index f6f148a340..80c3c7b391 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramProviderContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramProviderContext.java @@ -57,7 +57,8 @@ public class ProgramProviderContext implements DataTypeProviderContext { } DataType dt = data.getDataType(); - int length = data.getLength(); + int length = DataTypeComponentImpl.getPreferredComponentLength(dt, + Math.max(data.getLength(), dt.getAlignedLength())); String label = null; Symbol symbol = data.getPrimarySymbol(); if (symbol != null && !symbol.isDynamic()) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/BigFloat.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/BigFloat.java index b8c8b68e28..7d452a0300 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/BigFloat.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/BigFloat.java @@ -15,8 +15,9 @@ */ package ghidra.pcode.floatformat; -import java.math.BigDecimal; -import java.math.BigInteger; +import java.math.*; +import java.util.HashMap; +import java.util.Map; /** * An IEEE 754 floating point class. @@ -31,8 +32,20 @@ import java.math.BigInteger; * *
Operations compute exact result then round to nearest even.
*/
-public strictfp class BigFloat implements Comparable
* NOTE: Requires that normal values are constructed in a normal form as with denormal values.
*
- * @param fracbits number of fractional bits (positive non-zero value)
+ * @param fracbits number of fractional bits (positive non-zero value; includes additional
+ * implied bit if relavent).
* @param expbits maximum number of bits in exponent (positive non-zero value)
* @param kind the Kind, FINITE, INFINITE, ...
* @param sign +1 or -1
@@ -71,8 +87,8 @@ public strictfp class BigFloat implements Comparable
- * NOTE: No datatype should ever return 0, even if {@link #isZeroLength()}, and only
- * {@link Dynamic} datatypes should return -1. If {@link #isZeroLength()} is true a length of 1
- * should be returned. Where a zero-length datatype can be handled (e.g., {@link Composite}) the
+ * For primitive datatypes this reflects the smallest varnode which can be used to
+ * contain its value (i.e., raw data length).
+ *
+ * Example: For x86 32-bit gcc an 80-bit {@code long double} {@link #getLength() raw data length}
+ * of 10-bytes will fit within a floating point register while its {@link #getAlignedLength() aligned-length}
+ * of 12-bytes is used by the gcc compiler for data/array/component allocations to maintain alignment
+ * (i.e., {@code sizeof(long double)} ).
+ *
+ * NOTE: Other than the {@link VoidDataType}, no datatype should ever return 0, even if
+ * {@link #isZeroLength()}, and only {@link Dynamic}/{@link FactoryDataType} datatypes
+ * should return -1. If {@link #isZeroLength()} is true a length of 1 should be returned.
+ * Where a zero-length datatype can be handled (e.g., {@link Composite}) the
* {@link #isZeroLength()} method should be used.
*
* @return the length of this DataType
*/
public int getLength();
+ /**
+ * Get the aligned-length of this datatype as a number of 8-bit bytes.
+ *
+ * For primitive datatypes this is equivalent to the C/C++ "sizeof" operation within source code and
+ * should be used when determining {@link Array} element length or component sizing for a
+ * {@link Composite}. For {@link Pointer}, {@link Composite} and {@link Array} types this will
+ * return the same value as {@link #getLength()}.
+ *
+ * Example: For x86 32-bit gcc an 80-bit {@code long double} {@link #getLength() raw data length}
+ * of 10-bytes will fit within a floating point register while its {@link #getAlignedLength() aligned-length}
+ * of 12-bytes is used by the gcc compiler for data/array/component allocations to maintain alignment
+ * (i.e., {@code sizeof(long double)} ).
+ *
+ * NOTE: Other than the {@link VoidDataType}, no datatype should ever return 0, even if
+ * {@link #isZeroLength()}, and only {@link Dynamic} / {@link FactoryDataType} /
+ * {@link FunctionDefinition} datatypes should return -1. If {@link #isZeroLength()} is true
+ * a length of 1 should be returned.
+ *
+ * @return byte length of binary encoding.
+ */
+ public int getAlignedLength();
+
/**
* Indicates this datatype is defined with a zero length.
*
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeComponentImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeComponentImpl.java
index 403709ed27..690d72cfbe 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeComponentImpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeComponentImpl.java
@@ -347,4 +347,32 @@ public class DataTypeComponentImpl implements InternalDataTypeComponent, Seriali
return InternalDataTypeComponent.toString(this);
}
+ /**
+ * Get the preferred length for a new component. The length returned will be no
+ * larger than the specified length.
+ *
+ * @param dataType new component datatype
+ * @param length constrained length or -1 to force use of dataType size.
+ * Dynamic types such as string must have a positive length
+ * specified.
+ * @return preferred component length
+ */
+ public static int getPreferredComponentLength(DataType dataType, int length) {
+ if (DataTypeComponent.usesZeroLengthComponent(dataType)) {
+ return 0;
+ }
+ int dtLength = dataType.getAlignedLength();
+ if (length <= 0) {
+ length = dtLength;
+ }
+ else if (dtLength > 0 && dtLength < length) {
+ length = dtLength;
+ }
+ if (length <= 0) {
+ throw new IllegalArgumentException("Positive length must be specified for " +
+ dataType.getDisplayName() + " component");
+ }
+ return length;
+ }
+
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeImpl.java
index 79137ab7a8..59a7ef95a2 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeImpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeImpl.java
@@ -36,6 +36,8 @@ public abstract class DataTypeImpl extends AbstractDataType {
// defaultSettings implementation established by its DataTypeManager.
protected Settings defaultSettings;
+ private Integer alignedLength;
+
private Listsign*unscaled*2^(scale-fracbits).
* sign*unscaled*2^(scale-fracbits)
+ * Construct SmallFloat Data. (similar to BigFloat)
*
- * @param fracbits number of fractional bits
+ * @param fracbits number of fractional bits (positive non-zero value; includes additional
+ * implied bit if relavent).
* @param expbits maximum number of bits in exponent
* @param kind the Kind, FINITE, INFINITE, ...
* @param sign +1 or -1
@@ -700,6 +856,7 @@ public strictfp class FloatFormat {
*/
public SmallFloatData(int fracbits, int expbits, FloatKind kind, int sign, long unscaled,
int scale) {
+ // FIXME check use and changes to fracbits
this.fracbits = fracbits;
this.expbits = expbits;
this.kind = kind;
@@ -723,15 +880,15 @@ public strictfp class FloatFormat {
// The long methods should not be used when size>8.
public long opEqual(long a, long b) { // a == b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
long res = (val1 == val2) ? 1 : 0;
return res;
}
public BigInteger opEqual(BigInteger a, BigInteger b) { // a == b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
if (fa.isNaN() || fb.isNaN()) {
return BigInteger.ZERO;
}
@@ -740,15 +897,15 @@ public strictfp class FloatFormat {
}
public long opNotEqual(long a, long b) { // a != b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
long res = (val1 != val2) ? 1 : 0;
return res;
}
public BigInteger opNotEqual(BigInteger a, BigInteger b) { // a != b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
if (fa.isNaN() | fb.isNaN()) {
return BigInteger.ONE;
}
@@ -757,127 +914,127 @@ public strictfp class FloatFormat {
}
public long opLess(long a, long b) { // a < b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
long res = (val1 < val2) ? 1 : 0;
return res;
}
public BigInteger opLess(BigInteger a, BigInteger b) { // a < b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
BigInteger res = (fa.compareTo(fb) < 0) ? BigInteger.ONE : BigInteger.ZERO;
return res;
}
public long opLessEqual(long a, long b) { // a <= b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
long res = (val1 <= val2) ? 1 : 0;
return res;
}
public BigInteger opLessEqual(BigInteger a, BigInteger b) { // a <= b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
BigInteger res = (fa.compareTo(fb) <= 0) ? BigInteger.ONE : BigInteger.ZERO;
return res;
}
// true if a is "not a number"
public long opNan(long a) {
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
long res = Double.isNaN(val) ? 1 : 0;
return res;
}
public BigInteger opNan(BigInteger a) {
- BigFloat val = getHostFloat(a);
+ BigFloat val = decodeBigFloat(a);
BigInteger res = (val.isNaN()) ? BigInteger.ONE : BigInteger.ZERO;
return res;
}
public long opAdd(long a, long b) { // a + b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
return getEncoding(val1 + val2);
}
public BigInteger opAdd(BigInteger a, BigInteger b) { // a + b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
fa.add(fb);
return getEncoding(fa);
}
public long opSub(long a, long b) { // a - b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
return getEncoding(val1 - val2);
}
public BigInteger opSub(BigInteger a, BigInteger b) { // a - b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
fa.sub(fb);
return getEncoding(fa);
}
public long opDiv(long a, long b) { // a / b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
return getEncoding(val1 / val2);
}
public BigInteger opDiv(BigInteger a, BigInteger b) { // a / b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
fa.div(fb);
return getEncoding(fa);
}
public long opMult(long a, long b) { // a * b
- double val1 = getHostFloat(a);
- double val2 = getHostFloat(b);
+ double val1 = decodeHostFloat(a);
+ double val2 = decodeHostFloat(b);
return getEncoding(val1 * val2);
}
public BigInteger opMult(BigInteger a, BigInteger b) { // a * b
- BigFloat fa = getHostFloat(a);
- BigFloat fb = getHostFloat(b);
+ BigFloat fa = decodeBigFloat(a);
+ BigFloat fb = decodeBigFloat(b);
fa.mul(fb);
return getEncoding(fa);
}
public long opNeg(long a) { // -a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(-val);
}
public BigInteger opNeg(BigInteger a) {
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.negate();
return getEncoding(fa);
}
public long opAbs(long a) { // absolute value of a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(Math.abs(val));
}
public BigInteger opAbs(BigInteger a) {
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.abs();
return getEncoding(fa);
}
public long opSqrt(long a) { // square root of a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(Math.sqrt(val));
}
public BigInteger opSqrt(BigInteger a) {
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.sqrt();
return getEncoding(fa);
}
@@ -897,29 +1054,29 @@ public strictfp class FloatFormat {
else {
a = Utils.convertToUnsignedValue(a, sizein);
}
- return getEncoding(valueOf(a));
+ return getEncoding(getBigFloat(a));
}
public long opFloat2Float(long a, FloatFormat outformat) { // convert between floating
// point precisions
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return outformat.getEncoding(val);
}
public BigInteger opFloat2Float(BigInteger a, FloatFormat outformat) { // convert between floating
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
return outformat.getEncoding(fa);
}
public long opTrunc(long a, int sizeout) { // convert floating point to integer
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
long res = (long) val; // Convert to integer
res &= Utils.calc_mask(sizeout); // Truncate to proper size
return res;
}
public BigInteger opTrunc(BigInteger a, int sizeout) { // convert floating point to integer
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
if (fa.isNaN()) {
return BigInteger.ZERO; // consistent with Java Double->Long behavior
}
@@ -936,39 +1093,48 @@ public strictfp class FloatFormat {
}
public long opCeil(long a) { // integer ceiling of a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(Math.ceil(val));
}
public BigInteger opCeil(BigInteger a) { // integer ceiling of a
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.ceil();
return getEncoding(fa);
}
public long opFloor(long a) { // integer floor of a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(Math.floor(val));
}
public BigInteger opFloor(BigInteger a) { // integer floor of a
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.floor();
return getEncoding(fa);
}
public long opRound(long a) { // nearest integer to a
- double val = getHostFloat(a);
+ double val = decodeHostFloat(a);
return getEncoding(Math.floor(val + 0.5));
}
public BigInteger opRound(BigInteger a) { // nearest integer to a
- BigFloat fa = getHostFloat(a);
+ BigFloat fa = decodeBigFloat(a);
fa.round();
return getEncoding(fa);
}
- public BigFloat valueOf(BigInteger value) {
+ public BigFloat getBigFloat(BigInteger value) {
+
+ if (size == 8) {
+ double d = value.doubleValue();
+ return getBigFloat(d);
+ }
+ if (size == 4) {
+ float f = value.floatValue();
+ return getBigFloat(f);
+ }
BigInteger unscaled = value;
int sign = 1;
@@ -977,18 +1143,110 @@ public strictfp class FloatFormat {
unscaled = unscaled.negate();
}
+ int scale = effective_frac_size - 1;
int ulen = unscaled.bitLength();
- int shift = frac_size + 1 - ulen;
-
- unscaled = unscaled.shiftLeft(shift);
-
- int scale = frac_size - shift;
-
- if (scale > bias) {
- return BigFloat.infinity(frac_size, exp_size, sign);
+ if (ulen > effective_frac_size) {
+ int shift = effective_frac_size - ulen; // may produce +/- shift
+ unscaled = unscaled.shiftLeft(shift);
+ scale = effective_frac_size - shift - 1;
+ if (scale > bias) {
+ return BigFloat.infinity(effective_frac_size, exp_size, sign);
+ }
}
- return new BigFloat(frac_size, exp_size, FloatKind.FINITE, sign, unscaled, scale);
+ return new BigFloat(effective_frac_size, exp_size, FloatKind.FINITE, sign, unscaled, scale);
+ }
+
+ /**
+ * Constructs a {@code BigFloat} initialized to the value
+ * represented by the specified decimal {@code String}, as performed
+ * by {@link BigDecimal#BigDecimal(String)}. Other values permitted
+ * are (case-insenstive): "NaN", "Infinity", "+Infinity", "-Infinity"
+ * (See {@link BigFloat#NAN}, {@link BigFloat#INFINITY}, {@link BigFloat#POSITIVE_INFINITY},
+ * {@link BigFloat#NEGATIVE_INFINITY}).
+ *
+ * @param string the string to be parsed.
+ * @return value as a {@link BigFloat}
+ * @throws NullPointerException if the string is null
+ * @throws NumberFormatException if the string parse fails.
+ */
+ public BigFloat getBigFloat(String string) throws NumberFormatException {
+ java.util.Objects.requireNonNull(string);
+ if (string.equalsIgnoreCase(BigFloat.NAN)) {
+ return BigFloat.quietNaN(effective_frac_size, exp_size, 1);
+ }
+ if (string.equalsIgnoreCase(BigFloat.INFINITY) ||
+ string.equalsIgnoreCase(BigFloat.POSITIVE_INFINITY)) {
+ return BigFloat.infinity(effective_frac_size, exp_size, 1);
+ }
+ if (string.equalsIgnoreCase(BigFloat.NEGATIVE_INFINITY)) {
+ return BigFloat.infinity(effective_frac_size, exp_size, -1);
+ }
+ return getBigFloat(new BigDecimal(string));
+ }
+
+ /**
+ * Constructs a {@code BigFloat} initialized to the value
+ * represented by the specified {@code BigDecimal}.
+ *
+ * @param value the decimal value.
+ * @return value as a {@link BigFloat}
+ * @throws NullPointerException if the string is null
+ * @throws NumberFormatException if the string parse fails.
+ */
+ public BigFloat getBigFloat(BigDecimal value) {
+ if (size == 8) {
+ return getBigFloat(value.doubleValue());
+ }
+ if (size == 4) {
+ return getBigFloat(value.floatValue());
+ }
+
+ BigDecimal val = value;
+ if (val.equals(BigDecimal.ZERO)) {
+ return BigFloat.zero(effective_frac_size, exp_size);
+ }
+
+ BigFloat bf;
+ int scale10 = val.scale();
+ if (scale10 < 0) {
+ scale10 = -scale10;
+ BigInteger scalar = BigInteger.valueOf(10).pow(scale10);
+ if (scale10 / 0.3 > effective_frac_size) { // log10(2) = ~0.3
+ // will be whole integer
+ BigInteger intVal = scalar.multiply(val.unscaledValue());
+ bf = getBigFloat(intVal);
+ }
+ else {
+ // may have fractional value
+ BigFloat scalarBf = getBigFloat(scalar);
+ bf = getBigFloat(val.unscaledValue());
+ bf.mul(scalarBf);
+ }
+ }
+ else if (scale10 / 0.3 >= bias) { // log10(2) = ~0.3
+ // divide down in two passes to avoid divide by infinity for edge case
+ int s1 = scale10 / 2;
+ BigInteger bs1 = BigInteger.valueOf(10).pow(s1);
+ BigInteger bs2 = BigInteger.valueOf(10).pow(scale10 - s1);
+ BigFloat bf2 = getBigFloat(bs2);
+ if (bf2.isInfinite()) { // bf2 >= bf1
+ return BigFloat.zero(effective_frac_size, exp_size, value.signum());
+ }
+ BigFloat bf1 = getBigFloat(bs1);
+ bf = getBigFloat(val.unscaledValue());
+ bf.div(bf1);
+ bf.div(bf2);
+ }
+ else {
+ BigInteger scalar = BigInteger.valueOf(10).pow(scale10);
+ BigFloat scalarBf = getBigFloat(scalar);
+
+ BigInteger whole = val.unscaledValue();
+ bf = getBigFloat(whole);
+ bf.div(scalarBf);
+ }
+ return bf;
}
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/FloatFormatFactory.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/FloatFormatFactory.java
index 4e08d5f210..f8bd90cde8 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/FloatFormatFactory.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/floatformat/FloatFormatFactory.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +29,7 @@ public class FloatFormatFactory {
* Get float format
* @param size format storage size in bytes
* @return float format or null if size is not supported
+ * @throws UnsupportedFloatFormatException if specified size is unsupported
*/
public static synchronized FloatFormat getFloatFormat(int size)
throws UnsupportedFloatFormatException {
@@ -40,7 +40,6 @@ public class FloatFormatFactory {
cache.put(size, format);
}
return format;
-
}
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/DataDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/DataDB.java
index 3d41a57d4f..b9b285b40e 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/DataDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/DataDB.java
@@ -129,7 +129,8 @@ class DataDB extends CodeUnitDB implements Data {
}
private void computeLength() {
- length = dataType.getLength();
+ // NOTE: Data intentionally does not use aligned-length
+ length = dataType.getLength();
// undefined will never change their size
if (dataType instanceof Undefined) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ArrayDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ArrayDB.java
index 8041ef50cb..cc9d7c57c4 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ArrayDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ArrayDB.java
@@ -36,6 +36,7 @@ class ArrayDB extends DataTypeDB implements Array {
private volatile String displayName;
private ArrayDBAdapter adapter;
+ private int elementLength; // lazy initialization
/**
* Constructor
@@ -52,6 +53,7 @@ class ArrayDB extends DataTypeDB implements Array {
@Override
protected String doGetName() {
+ elementLength = -1; // signal refresh by getElementLength()
return DataTypeUtilities.getName(this, true);
}
@@ -74,6 +76,7 @@ class ArrayDB extends DataTypeDB implements Array {
@Override
protected boolean refresh() {
try {
+ elementLength = -1;
DBRecord rec = adapter.getRecord(key);
if (rec != null) {
record = rec;
@@ -129,6 +132,11 @@ class ArrayDB extends DataTypeDB implements Array {
return getNumElements() * getElementLength();
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public String getDescription() {
checkIsValid();
@@ -169,15 +177,23 @@ class ArrayDB extends DataTypeDB implements Array {
@Override
public int getElementLength() {
- DataType dt = getDataType();
- int elementLen;
- if (dt instanceof Dynamic) {
- elementLen = record.getIntValue(ArrayDBAdapter.ARRAY_ELEMENT_LENGTH_COL);
+ lock.acquire();
+ try {
+ checkIsValid();
+ DataType dt = getDataType();
+ if (elementLength < 0) {
+ if (dt instanceof Dynamic) {
+ elementLength = record.getIntValue(ArrayDBAdapter.ARRAY_ELEMENT_LENGTH_COL);
+ }
+ else {
+ elementLength = dt.getAlignedLength();
+ }
+ }
+ return elementLength;
}
- else {
- elementLen = dt.getLength();
+ finally {
+ lock.release();
}
- return elementLen;
}
@Override
@@ -251,7 +267,7 @@ class ArrayDB extends DataTypeDB implements Array {
if (newDt instanceof Dynamic || newDt instanceof FactoryDataType) {
newDt = DataType.DEFAULT;
}
- int elementLength = newDt.getLength() < 0 ? oldElementLength : -1;
+ elementLength = newDt.getLength() < 0 ? oldElementLength : -1;
record.setIntValue(ArrayDBAdapter.ARRAY_ELEMENT_LENGTH_COL, elementLength);
try {
adapter.updateRecord(record);
@@ -288,7 +304,8 @@ class ArrayDB extends DataTypeDB implements Array {
public void dataTypeSizeChanged(DataType dt) {
lock.acquire();
try {
- if (checkIsValid() && dt == getDataType()) {
+ if (checkIsValid() && dt == getDataType() && dt.getLength() > 0) {
+ elementLength = -1;
notifySizeChanged(true);
}
}
@@ -333,6 +350,7 @@ class ArrayDB extends DataTypeDB implements Array {
@Override
public void dataTypeDeleted(DataType dt) {
if (getDataType() == dt) {
+ elementLength = -1;
dataMgr.addDataTypeToDelete(key);
}
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/CompositeDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/CompositeDB.java
index c27e3fe2ee..d17f64ce8c 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/CompositeDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/CompositeDB.java
@@ -59,6 +59,11 @@ abstract class CompositeDB extends DataTypeDB implements CompositeInternal {
*/
protected abstract void initialize();
+ @Override
+ public final int getAlignedLength() {
+ return getLength();
+ }
+
/**
* Get the preferred length for a new component. For Unions and packed
* structures the preferred component length for a fixed-length dataType
@@ -78,18 +83,7 @@ abstract class CompositeDB extends DataTypeDB implements CompositeInternal {
if ((isPackingEnabled() || (this instanceof Union)) && !(dataType instanceof Dynamic)) {
length = -1; // force use of datatype size
}
- int dtLength = dataType.getLength();
- if (length <= 0) {
- length = dtLength;
- }
- else if (dtLength > 0 && dtLength < length) {
- length = dtLength;
- }
- if (length <= 0) {
- throw new IllegalArgumentException("Positive length must be specified for " +
- dataType.getDisplayName() + " component");
- }
- return length;
+ return DataTypeComponentImpl.getPreferredComponentLength(dataType, length);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java
index 91f137e655..1e303fdd64 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeUtilities.java
@@ -23,6 +23,7 @@ import ghidra.app.util.SymbolPathParser;
import ghidra.docking.settings.Settings;
import ghidra.program.model.data.*;
import ghidra.program.model.data.Enum;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Namespace;
import ghidra.util.UniversalID;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
index 1b1bc33bb3..5d32fcd8b1 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
@@ -453,6 +453,11 @@ class EnumDB extends DataTypeDB implements Enum {
}
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public String getDescription() {
lock.acquire();
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/FunctionDefinitionDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/FunctionDefinitionDB.java
index 9c1ccb91d2..94af56ce3f 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/FunctionDefinitionDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/FunctionDefinitionDB.java
@@ -254,6 +254,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
return -1;
}
+ @Override
+ public int getAlignedLength() {
+ return -1;
+ }
+
@Override
public String getDescription() {
return "Function Signature Data Type";
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/PointerDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/PointerDB.java
index 5ecedcfa4c..8cc2cef715 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/PointerDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/PointerDB.java
@@ -207,6 +207,12 @@ class PointerDB extends DataTypeDB implements Pointer {
}
}
+ @Override
+ public int getAlignedLength() {
+ // assume pointers are never padded
+ return getLength();
+ }
+
@Override
public String getDescription() {
lock.acquire();
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java
index 19987ba5ac..2858250ccf 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/StructureDB.java
@@ -1709,7 +1709,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
DataTypeComponent dtc = otherComponents[i];
DataType dt = resolvedDts[i]; // ancestry check already performed by caller
- int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength();
+ int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getAlignedLength();
if (length < 0 || dtc.isBitFieldComponent()) {
// TODO: bitfield truncation/expansion may be an issue if data organization changes
length = dtc.getLength();
@@ -1817,7 +1817,8 @@ class StructureDB extends CompositeDB implements StructureInternal {
if (dtc.getDataType() == dt) {
// assume no impact to bitfields since base types should not change size
int dtcLen = dtc.getLength();
- int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength();
+ int length =
+ DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getAlignedLength();
if (length < 0) {
length = dtcLen;
}
@@ -1875,7 +1876,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
forceRepack |= isPacked;
continue;
}
- int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength();
+ int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getAlignedLength();
if (length < 0) {
continue; // illegal condition - skip
}
@@ -2304,7 +2305,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
int nextIndex) throws IOException {
int oldLen = comp.getLength();
- int len = DataTypeComponent.usesZeroLengthComponent(newDt) ? 0 : newDt.getLength();
+ int len = DataTypeComponent.usesZeroLengthComponent(newDt) ? 0 : newDt.getAlignedLength();
if (len < 0) {
len = oldLen;
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/TypedefDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/TypedefDB.java
index 26603e5ff1..2fd7f22c51 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/TypedefDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/TypedefDB.java
@@ -154,6 +154,11 @@ class TypedefDB extends DataTypeDB implements TypeDef {
return getDataType().getLength();
}
+ @Override
+ public int getAlignedLength() {
+ return getDataType().getAlignedLength();
+ }
+
@Override
public String getDescription() {
return getDataType().getDescription();
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/UnionDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/UnionDB.java
index 3072a52070..973b511e92 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/UnionDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/UnionDB.java
@@ -487,7 +487,7 @@ class UnionDB extends CompositeDB implements UnionInternal {
if (dt instanceof BitFieldDataType) {
dt = adjustBitField(dt); // in case base type changed
}
- int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength();
+ int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getAlignedLength();
if (length < 0) {
continue; // illegal condition - skip
}
@@ -533,7 +533,8 @@ class UnionDB extends CompositeDB implements UnionInternal {
boolean changed = false;
for (DataTypeComponentDB dtc : components) {
if (dtc.getDataType() == dt) {
- int length = DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getLength();
+ int length =
+ DataTypeComponent.usesZeroLengthComponent(dt) ? 0 : dt.getAlignedLength();
if (length >= 0 && length != dtc.getLength()) {
dtc.setLength(length, true);
changed = true;
@@ -824,7 +825,7 @@ class UnionDB extends CompositeDB implements UnionInternal {
}
else {
int len = DataTypeComponent.usesZeroLengthComponent(newDt) ? 0
- : newDt.getLength();
+ : newDt.getAlignedLength();
if (len < 0) {
len = dtc.getLength();
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractComplexDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractComplexDataType.java
index bbb7088c82..b2c7000d51 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractComplexDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractComplexDataType.java
@@ -19,6 +19,7 @@ import java.math.BigDecimal;
import generic.complex.Complex;
import ghidra.docking.settings.Settings;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.WrappedMemBuffer;
@@ -86,9 +87,15 @@ public abstract class AbstractComplexDataType extends BuiltIn {
return floatType.getLength() * 2;
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public String getDescription() {
- return "The data type for a complex number: a + bi";
+ return "The data type for a complex number: a + bi; consisting of two " +
+ floatType.getName() + " values";
}
private static double toDouble(Object obj) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractDataType.java
index 2aa7b34763..99e3f6a146 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractDataType.java
@@ -78,6 +78,25 @@ public abstract class AbstractDataType implements DataType {
: DataOrganizationImpl.getDefaultOrganization();
}
+ /**
+ * Get the {@link DataOrganization} which should be used by a {@link AbstractDataType} when
+ * associated with a specified {@link DataTypeManager dataMgr}. If a null
+ * {@code dataMgr} is specified the default {@link DataOrganization} will be returned.
+ * @param dataMgr datatype manager
+ * @return the {@link DataOrganization} which should be used by a {@link AbstractDataType}
+ * instance.
+ */
+ protected static DataOrganization getDataOrganization(DataTypeManager dataMgr) {
+ DataOrganization dataOrganization = null;
+ if (dataMgr != null) {
+ dataOrganization = dataMgr.getDataOrganization();
+ }
+ if (dataOrganization == null) {
+ dataOrganization = DataOrganizationImpl.getDefaultOrganization();
+ }
+ return dataOrganization;
+ }
+
@Override
public DataTypePath getDataTypePath() {
// use methods instead of fields since they mey be overriden
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractPointerTypedefBuiltIn.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractPointerTypedefBuiltIn.java
index ba43d4fa1d..954f940567 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractPointerTypedefBuiltIn.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractPointerTypedefBuiltIn.java
@@ -150,6 +150,11 @@ public abstract class AbstractPointerTypedefBuiltIn extends BuiltIn implements T
return modelTypedef.getLength();
}
+ @Override
+ public int getAlignedLength() {
+ return modelTypedef.getAlignedLength();
+ }
+
@Override
public DataType getDataType() {
return modelTypedef.getDataType();
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AlignedComponentPacker.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AlignedComponentPacker.java
index 06895671b5..13343fade2 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AlignedComponentPacker.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AlignedComponentPacker.java
@@ -299,7 +299,7 @@ class AlignedComponentPacker {
int minOffset) {
DataType componentDt = dataTypeComponent.getDataType();
- int dtSize = componentDt.isZeroLength() ? 0 : componentDt.getLength();
+ int dtSize = componentDt.isZeroLength() ? 0 : componentDt.getAlignedLength();
if (dtSize < 0) {
dtSize = dataTypeComponent.getLength();
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ArrayDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ArrayDataType.java
index f16b2e739d..b280085b17 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ArrayDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/ArrayDataType.java
@@ -56,6 +56,10 @@ public class ArrayDataType extends DataTypeImpl implements Array {
public ArrayDataType(DataType dataType, int numElements, int elementLength,
DataTypeManager dtm) {
super(dataType.getCategoryPath(), "array", dtm);
+ if (dataType instanceof FactoryDataType) {
+ throw new IllegalArgumentException(
+ "Factory data type not permitted");
+ }
if (numElements < 0) {
throw new IllegalArgumentException(
"Number of array elements may not be negative [" + numElements + "]");
@@ -75,6 +79,9 @@ public class ArrayDataType extends DataTypeImpl implements Array {
}
this.elementLength = elementLength;
}
+ else {
+ this.elementLength = dataType.getAlignedLength();
+ }
this.dataType = dataType;
this.numElements = numElements;
name = DataTypeUtilities.getName(this, true);
@@ -168,6 +175,11 @@ public class ArrayDataType extends DataTypeImpl implements Array {
return numElements * getElementLength();
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public String getDescription() {
return "Array of " + dataType.getDisplayName();
@@ -193,7 +205,8 @@ public class ArrayDataType extends DataTypeImpl implements Array {
@Override
public void dataTypeSizeChanged(DataType dt) {
- if (dt == dataType) {
+ if (dt == dataType && dt.getLength() > 0) {
+ elementLength = dataType.getAlignedLength();
notifySizeChanged();
}
}
@@ -217,7 +230,7 @@ public class ArrayDataType extends DataTypeImpl implements Array {
@Override
public int getElementLength() {
- return (dataType instanceof Dynamic) ? elementLength : dataType.getLength();
+ return elementLength;
}
@Override
@@ -246,7 +259,9 @@ public class ArrayDataType extends DataTypeImpl implements Array {
dataType.removeParent(this);
dataType = newDt;
dataType.addParent(this);
- elementLength = newDt.getLength() < 0 ? oldElementLength : -1;
+ if (dataType.getLength() >= 0) {
+ elementLength = dataType.getAlignedLength();
+ }
if (!getName().equals(oldName)) {
notifyNameChanged(oldName);
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java
index 9a3d09b951..5b6acad76f 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java
@@ -15,9 +15,8 @@
*/
package ghidra.program.model.data;
-import java.util.*;
-
import java.math.BigInteger;
+import java.util.*;
import ghidra.docking.settings.*;
import ghidra.program.model.mem.MemBuffer;
@@ -336,6 +335,11 @@ public class BitFieldDataType extends AbstractDataType {
return storageSize;
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public String getDescription() {
StringBuffer sbuf = new StringBuffer();
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex16DataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex16DataType.java
index 70d9c8db3a..22c6f9a6e9 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex16DataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex16DataType.java
@@ -15,8 +15,10 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.Float64DataType;
+
/**
- * Provides a definition of a {@code complex} built-in data type consisting of two 8 byte floating point
+ * Provides a definition of a {@code complex} built-in data type consisting of two 64-bit floating point
* numbers in the IEEE 754 double precision format.
*/
public class Complex16DataType extends AbstractComplexDataType {
@@ -28,7 +30,7 @@ public class Complex16DataType extends AbstractComplexDataType {
}
public Complex16DataType(DataTypeManager dtm) {
- super("complex16", Float8DataType.dataType, dtm);
+ super("complex16", Float64DataType.dataType, dtm);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex32DataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex32DataType.java
index 7acbdcd3ee..962733da77 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex32DataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex32DataType.java
@@ -15,8 +15,10 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.Float128DataType;
+
/**
- * Provides a definition of a {@code complex} built-in data type consisting of two 16 byte floating point
+ * Provides a definition of a {@code complex} built-in data type consisting of two 128-bit floating point
* numbers in the IEEE 754 double precision format.
*/
public class Complex32DataType extends AbstractComplexDataType {
@@ -28,7 +30,7 @@ public class Complex32DataType extends AbstractComplexDataType {
}
public Complex32DataType(DataTypeManager dtm) {
- super("complex32", Float16DataType.dataType, dtm);
+ super("complex32", Float128DataType.dataType, dtm);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex8DataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex8DataType.java
index d30e9feb4e..9f13ea46de 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex8DataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Complex8DataType.java
@@ -15,8 +15,10 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.Float32DataType;
+
/**
- * Provides a definition of a {@code complex} built-in data type consisting of two 4 byte floating point
+ * Provides a definition of a {@code complex} built-in data type consisting of two 32-bit floating point
* numbers in the IEEE 754 double precision format.
*/
@@ -29,7 +31,7 @@ public class Complex8DataType extends AbstractComplexDataType {
}
public Complex8DataType(DataTypeManager dtm) {
- super("complex8", Float4DataType.dataType, dtm);
+ super("complex8", Float32DataType.dataType, dtm);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CompositeDataTypeImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CompositeDataTypeImpl.java
index dedcad2a3e..f267648884 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CompositeDataTypeImpl.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CompositeDataTypeImpl.java
@@ -62,6 +62,11 @@ public abstract class CompositeDataTypeImpl extends GenericDataType implements C
description = "";
}
+ @Override
+ public final int getAlignedLength() {
+ return getLength();
+ }
+
@Override
public int getStoredPackingValue() {
return packing;
@@ -96,18 +101,7 @@ public abstract class CompositeDataTypeImpl extends GenericDataType implements C
if ((isPackingEnabled() || (this instanceof Union)) && !(dataType instanceof Dynamic)) {
length = -1; // force use of datatype size
}
- int dtLength = dataType.getLength();
- if (length <= 0) {
- length = dtLength;
- }
- else if (dtLength > 0 && dtLength < length) {
- length = dtLength;
- }
- if (length <= 0) {
- throw new IllegalArgumentException("Positive length must be specified for " +
- dataType.getDisplayName() + " component");
- }
- return length;
+ return DataTypeComponentImpl.getPreferredComponentLength(dataType, length);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CountedDynamicDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CountedDynamicDataType.java
index 0af861f420..200bb5c8ef 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CountedDynamicDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/CountedDynamicDataType.java
@@ -79,7 +79,7 @@ public abstract class CountedDynamicDataType extends DynamicDataType {
int n = (int) getCount(memory, start.add(counterOffset));
DataTypeComponent[] comps = new DataTypeComponent[n + 1];
- DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(header, buf);
+ DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(header, buf, false);
if (dti == null) {
Msg.error(this, "ERROR: problem with data at " + buf.getAddress());
@@ -94,7 +94,7 @@ public abstract class CountedDynamicDataType extends DynamicDataType {
try {
newBuf.advance(countSize);
for (int i = 1; i <= n; i++) {
- dti = DataTypeInstance.getDataTypeInstance(baseStruct, buf);
+ dti = DataTypeInstance.getDataTypeInstance(baseStruct, buf, false);
if (dti == null) {
Msg.error(this, "ERROR: problem with data at " + buf.getAddress());
return null;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganization.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganization.java
index c15d05ba0b..1239457ccb 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganization.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataOrganization.java
@@ -15,7 +15,7 @@
*/
package ghidra.program.model.data;
-import ghidra.util.exception.NoValueException;
+import java.util.Arrays;
public interface DataOrganization {
@@ -75,17 +75,17 @@ public interface DataOrganization {
int getLongLongSize();
/**
- * @return the size of a float primitive data type in bytes.
+ * @return the encoding size of a float primitive data type in bytes.
*/
int getFloatSize();
/**
- * @return the size of a double primitive data type in bytes.
+ * @return the encoding size of a double primitive data type in bytes.
*/
int getDoubleSize();
/**
- * @return the size of a long double primitive data type in bytes.
+ * @return the encoding size of a long double primitive data type in bytes.
*/
int getLongDoubleSize();
@@ -119,12 +119,14 @@ public interface DataOrganization {
int getDefaultPointerAlignment();
/**
- * Gets the alignment that is defined for a data type of the indicated size if one is defined.
- * @param size the size of the data type
+ * Gets the primitive data alignment that is defined for the specified size. If no entry has
+ * been defined for the specified size alignment of the next smaller map entry will be returned.
+ * If the map is empty the {@link #getDefaultAlignment() default alignment}. The returned
+ * value will not exceed the {@link #getAbsoluteMaxAlignment() defined maximum alignment}.
+ * @param size the primitive data size
* @return the alignment of the data type.
- * @throws NoValueException if there isn't an alignment defined for the indicated size.
*/
- int getSizeAlignment(int size) throws NoValueException;
+ int getSizeAlignment(int size);
/**
* Get the composite bitfield packing information associated with this data organization.
@@ -139,8 +141,8 @@ public interface DataOrganization {
int getSizeAlignmentCount();
/**
- * Gets the sizes that have an alignment specified.
- * @return the sizes with alignments mapped to them.
+ * Gets the ordered list of sizes that have an alignment specified.
+ * @return the ordered list of sizes with alignments mapped to them.
*/
int[] getSizes();
@@ -213,19 +215,14 @@ public interface DataOrganization {
}
int[] keys = getSizes();
int[] op2keys = obj.getSizes();
- if (keys.length != op2keys.length) {
+ if (!Arrays.equals(keys, op2keys)) {
return false;
}
- try {
- for (int k : keys) {
- if (getSizeAlignment(k) != obj.getSizeAlignment(k)) {
- return false;
- }
+ for (int k : keys) {
+ if (getSizeAlignment(k) != obj.getSizeAlignment(k)) {
+ return false;
}
}
- catch (NoValueException ex) {
- return false;
- }
return true;
}
}
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 b16292b30d..0c3090979b 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
@@ -20,11 +20,11 @@ import static ghidra.program.model.pcode.ElementId.*;
import java.io.IOException;
import java.util.*;
+import java.util.Map.Entry;
import ghidra.program.database.DBStringMapAdapter;
import ghidra.program.model.lang.Language;
import ghidra.program.model.pcode.Encoder;
-import ghidra.util.exception.NoValueException;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
@@ -48,9 +48,9 @@ public class DataOrganizationImpl implements DataOrganization {
public static final int DEFAULT_INT_SIZE = 4;
public static final int DEFAULT_LONG_SIZE = 4;
public static final int DEFAULT_LONG_LONG_SIZE = 8;
- public static final int DEFAULT_FLOAT_SIZE = 4;
- public static final int DEFAULT_DOUBLE_SIZE = 8;
- public static final int DEFAULT_LONG_DOUBLE_SIZE = 8;
+ public static final int DEFAULT_FLOAT_SIZE = 4; // encoding size only
+ public static final int DEFAULT_DOUBLE_SIZE = 8; // encoding size only
+ public static final int DEFAULT_LONG_DOUBLE_SIZE = 8; // encoding size only
// DBStringMapAdapter save/restore keys
private static final String BIG_ENDIAN_NAME = "big_endian";
@@ -83,7 +83,7 @@ public class DataOrganizationImpl implements DataOrganization {
/*
* Map for determining the alignment of a data type based upon its size.
*/
- private final HashMap
+ * NOTE: fixed-length primitive datatypes assume {@link DataType#getLength() raw datatype length}
+ * intended for {@link Data} use.
*
* @param dt data type
* @param length fixed length of the data type
@@ -66,25 +69,44 @@ public class DataTypeInstance {
this.length = length;
}
+ @Override
+ public String toString() {
+ return dataType.toString();
+ }
+
/**
* Generate a data-type instance
* Factory and Dynamic data-types are NOT handled.
- * @param dataType
- * @param buf
+ * @param dataType data type
+ * @param buf memory buffer
+ * @param useAlignedLength if true a fixed-length primitive data type will use its
+ * {@link DataType#getAlignedLength() aligned-length}, otherwise it will use its
+ * {@link DataType#getLength() raw length}. NOTE: This generally only relates to
+ * float datatypes whose raw encoding length may be shorter than their aligned-length
+ * generally corresponding to a compiler's "sizeof(type)" value. This should generally be
+ * true for {@link DataTypeComponent} and false for simple {@link Data} instances.
* @return data-type instance or null if one could not be determined
*/
- public static DataTypeInstance getDataTypeInstance(DataType dataType, MemBuffer buf) {
- return getDataTypeInstance(dataType, buf, -1);
+ public static DataTypeInstance getDataTypeInstance(DataType dataType, MemBuffer buf,
+ boolean useAlignedLength) {
+ return getDataTypeInstance(dataType, buf, -1, useAlignedLength);
}
/**
* Attempt to create a fixed-length data-type instance.
* Factory and non-sizable Dynamic data-types are NOT handled.
- * @param dataType
+ * @param dataType data type
* @param length length for sizable Dynamic data-types, otherwise ignored
+ * @param useAlignedLength if true a fixed-length primitive data type will use its
+ * {@link DataType#getAlignedLength() aligned-length}, otherwise it will use its
+ * {@link DataType#getLength() raw length}. NOTE: This generally only relates to
+ * float datatypes whose raw encoding length may be shorter than their aligned-length
+ * generally corresponding to a compiler's "sizeof(type)" value. This should generally be
+ * true for {@link DataTypeComponent} and false for simple {@link Data} instances.
* @return data-type instance or null if unable to create instance.
*/
- public static DataTypeInstance getDataTypeInstance(DataType dataType, int length) {
+ public static DataTypeInstance getDataTypeInstance(DataType dataType, int length,
+ boolean useAlignedLength) {
if (dataType == null) {
return null;
}
@@ -105,6 +127,9 @@ public class DataTypeInstance {
return null;
}
}
+ else if (useAlignedLength) {
+ length = dataType.getAlignedLength();
+ }
else {
length = dataType.getLength();
}
@@ -116,20 +141,26 @@ public class DataTypeInstance {
return new DataTypeInstance(dataType, length);
}
- @Override
- public String toString() {
- return dataType.toString();
- }
-
/**
* Attempt to create a data-type instance associated with a specific memory location.
* Factory and Dynamic data-types are handled.
+ *
+ * NOTE: fixed-length primitive datatypes assume {@link DataType#getLength() raw datatype length}
+ * intended for {@link Data} use.
+ *
* @param dataType
* @param buf memory location
* @param length length for sizable Dynamic data-types, otherwise ignored
+ * @param useAlignedLength if true a fixed-length primitive data type will use its
+ * {@link DataType#getAlignedLength() aligned-length}, otherwise it will use its
+ * {@link DataType#getLength() raw length}. NOTE: This generally only relates to
+ * float datatypes whose raw encoding length may be shorter than their aligned-length
+ * generally corresponding to a compiler's "sizeof(type)" value. This should generally be
+ * true for {@link DataTypeComponent} and false for simple {@link Data} instances.
* @return data-type instance or null if unable to create instance.
*/
- public static DataTypeInstance getDataTypeInstance(DataType dataType, MemBuffer buf, int length) {
+ public static DataTypeInstance getDataTypeInstance(DataType dataType, MemBuffer buf, int length,
+ boolean useAlignedLength) {
if (dataType instanceof FactoryDataType) {
dataType = ((FactoryDataType) dataType).getDataType(buf);
length = -1; // ignore user-specified length for factory use
@@ -151,6 +182,9 @@ public class DataTypeInstance {
Dynamic dynamicDataType = (Dynamic) dataType;
length = dynamicDataType.getLength(buf, length);
}
+ else if (useAlignedLength) {
+ length = dataType.getAlignedLength();
+ }
else {
length = dataType.getLength();
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java
index 41172cb83b..4b88c7840d 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java
@@ -259,10 +259,10 @@ public final class DataUtilities {
DataTypeInstance dti;
if (length > 0 && (realType instanceof Dynamic) &&
((Dynamic) realType).canSpecifyLength()) {
- dti = DataTypeInstance.getDataTypeInstance(newType, memBuf, length);
+ dti = DataTypeInstance.getDataTypeInstance(newType, memBuf, length, false);
}
else {
- dti = DataTypeInstance.getDataTypeInstance(newType, memBuf);
+ dti = DataTypeInstance.getDataTypeInstance(newType, memBuf, false);
}
if (dti == null) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DoubleDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DoubleDataType.java
index c9d79568d5..ca5bd1435a 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DoubleDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DoubleDataType.java
@@ -15,6 +15,7 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
/**
* Provides a definition of a Double within a program.
@@ -31,7 +32,12 @@ public class DoubleDataType extends AbstractFloatDataType {
}
public DoubleDataType(DataTypeManager dtm) {
- super("double", dtm);
+ super("double", getDataOrganization(dtm).getDoubleSize(), dtm);
+ }
+
+ @Override
+ protected String buildDescription() {
+ return "Compiler-defined 'double' " + super.buildDescription();
}
public DataType clone(DataTypeManager dtm) {
@@ -46,9 +52,4 @@ public class DoubleDataType extends AbstractFloatDataType {
return true;
}
- @Override
- public int getLength() {
- return getDataOrganization().getDoubleSize();
- }
-
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
index bb883e7b52..192e564c57 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
@@ -239,6 +239,11 @@ public class EnumDataType extends GenericDataType implements Enum {
return length;
}
+ @Override
+ public int getAlignedLength() {
+ return getLength();
+ }
+
public void setLength(int newLength) {
if (newLength == length) {
return;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FactoryStructureDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FactoryStructureDataType.java
index 3c2ac11b3f..d2c1eacede 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FactoryStructureDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FactoryStructureDataType.java
@@ -137,7 +137,7 @@ public abstract class FactoryStructureDataType extends BuiltIn implements Factor
protected DataTypeComponent addComponent(Structure es, DataType dt, String componentName) {
- return es.add(dt, dt.getLength(), componentName, null);
+ return es.add(dt, dt.getAlignedLength(), componentName, null);
}
protected abstract void populateDynamicStructure(MemBuffer buf, Structure es);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Float8DataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Float8DataType.java
deleted file mode 100644
index f94e622d6c..0000000000
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Float8DataType.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package ghidra.program.model.data;
-
-public class Float8DataType extends AbstractFloatDataType {
-
- public static final Float8DataType dataType = new Float8DataType();
-
- public Float8DataType() {
- this(null);
- }
-
- public Float8DataType(DataTypeManager dtm) {
- super("float8", dtm);
- }
-
- @Override
- public DataType clone(DataTypeManager dtm) {
- if (dtm == getDataTypeManager()) {
- return this;
- }
- return new Float8DataType(dtm);
- }
-
- @Override
- public int getLength() {
- return 8;
- }
-
-}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FloatDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FloatDataType.java
index 1067c281c2..8504a7901a 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FloatDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/FloatDataType.java
@@ -15,6 +15,8 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
+
/**
* Provides a definition of a Float within a program.
*/
@@ -30,7 +32,12 @@ public class FloatDataType extends AbstractFloatDataType {
}
public FloatDataType(DataTypeManager dtm) {
- super("float", dtm);
+ super("float", getDataOrganization(dtm).getFloatSize(), dtm);
+ }
+
+ @Override
+ protected String buildDescription() {
+ return "Compiler-defined 'float' " + super.buildDescription();
}
@Override
@@ -46,9 +53,4 @@ public class FloatDataType extends AbstractFloatDataType {
return true;
}
- @Override
- public int getLength() {
- return getDataOrganization().getFloatSize();
- }
-
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/IndexedDynamicDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/IndexedDynamicDataType.java
index b519e1ac09..ea24a1237c 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/IndexedDynamicDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/IndexedDynamicDataType.java
@@ -169,7 +169,7 @@ public abstract class IndexedDynamicDataType extends DynamicDataType {
comps = new DataTypeComponent[2];
}
MemoryBufferImpl newBuf = new MemoryBufferImpl(memory, buf.getAddress());
- DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(header, newBuf);
+ DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(header, newBuf, false);
if (dti == null) {
Msg.error(this, "ERROR: problem with data at " + newBuf.getAddress());
return null;
@@ -183,7 +183,7 @@ public abstract class IndexedDynamicDataType extends DynamicDataType {
int offset = countSize;
newBuf = new MemoryBufferImpl(memory, buf.getAddress());
newBuf.advance(countSize);
- dti = DataTypeInstance.getDataTypeInstance(data, newBuf);
+ dti = DataTypeInstance.getDataTypeInstance(data, newBuf, false);
if (dti == null) {
Msg.error(this, "ERROR: problem with data at " + newBuf.getAddress());
return null;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/LongDoubleDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/LongDoubleDataType.java
index 0af76c9f4e..5ca62c22fa 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/LongDoubleDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/LongDoubleDataType.java
@@ -15,6 +15,7 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
/**
* Provides a definition of a Long Double within a program.
@@ -31,7 +32,12 @@ public class LongDoubleDataType extends AbstractFloatDataType {
}
public LongDoubleDataType(DataTypeManager dtm) {
- super("longdouble", dtm);
+ super("longdouble", getDataOrganization(dtm).getLongDoubleSize(), dtm);
+ }
+
+ @Override
+ protected String buildDescription() {
+ return "Compiler-defined 'long double' " + super.buildDescription();
}
public DataType clone(DataTypeManager dtm) {
@@ -50,9 +56,4 @@ public class LongDoubleDataType extends AbstractFloatDataType {
public boolean hasLanguageDependantLength() {
return true;
}
-
- @Override
- public int getLength() {
- return getDataOrganization().getLongDoubleSize();
- }
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MetaDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MetaDataType.java
index fccda02918..fe80736638 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MetaDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/MetaDataType.java
@@ -15,6 +15,8 @@
*/
package ghidra.program.model.data;
+import ghidra.program.model.data.floats.AbstractFloatDataType;
+
public enum MetaDataType {
// Enumerations are ordered in terms of how "specific" the data-type class is
VOID, // "void" data-type
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/NoisyStructureBuilder.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/NoisyStructureBuilder.java
index e88712769e..c3e46b015e 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/NoisyStructureBuilder.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/NoisyStructureBuilder.java
@@ -31,6 +31,9 @@ import ghidra.program.model.pcode.PartialUnion;
* In a conflict, less specific data-types are replaced.
* After all information is collected a final Structure can be built by iterating over
* the final field entries.
+ *
+ * NOTE: No attempt has been made to utilize {@link DataType#getAlignedLength()} when considering
+ * component type lengths.
*/
public class NoisyStructureBuilder {
private TreeMap