diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/BitFieldPlacementComponent.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/BitFieldPlacementComponent.java index 34bccd9cff..0c8e094bf3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/BitFieldPlacementComponent.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/BitFieldPlacementComponent.java @@ -30,7 +30,7 @@ import ghidra.util.exception.AssertException; import ghidra.util.layout.VerticalLayout; import resources.icons.ColorIcon; -public class BitFieldPlacementComponent extends JPanel { +public class BitFieldPlacementComponent extends JPanel implements Scrollable { private static final int CELL_HEIGHT = 25; private static final int ZERO_BIT_WIDTH = 3; @@ -145,6 +145,33 @@ public class BitFieldPlacementComponent extends JPanel { init(null); } + @Override + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + // NOTE: consider forcing visibleRect edge alignment to byte boundary based upon direction + return byteWidth; + } + + @Override + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + // NOTE: consider forcing visibleRect edge alignment to byte boundary based upon direction + return visibleRect.width; + } + + @Override + public boolean getScrollableTracksViewportWidth() { + return false; + } + + @Override + public boolean getScrollableTracksViewportHeight() { + return true; + } + private class MyMouseWheelListener implements MouseWheelListener { @Override diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeVariableAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeVariableAction.java index b4744bfe23..17a4f4644b 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeVariableAction.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeVariableAction.java @@ -303,7 +303,8 @@ public class RetypeVariableAction extends AbstractDecompilerAction { return true; } VariableStorage storage = param.getStorage(); - if (!storage.equals(parameters[i].getVariableStorage())) { + // Don't compare using the equals method so that DynamicVariableStorage can match + if (0 != storage.compareTo(parameters[i].getVariableStorage())) { return true; } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunctionDBUtil.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunctionDBUtil.java index 258e9a13f9..4a2badffc7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunctionDBUtil.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunctionDBUtil.java @@ -359,12 +359,13 @@ public class HighFunctionDBUtil { } /** - * Get database parameter which corresponds to HighParam committing all parameters to - * database if necessary - * @param param - * @return matching parameter or null if not found - * @throws DuplicateNameException - * @throws InvalidInputException + * Get database parameter which corresponds to HighParam, where we anticipate that + * the parameter will be modified to match the HighParam. The entire prototype is + * committed to the database if necessary. An exception is thrown if a modifiable parameter + * can't be found/created. + * @param param is the HighParam describing the desired function parameter + * @return the matching parameter that can be modified + * @throws InvalidInputException if the desired parameter cannot be modified */ private static Parameter getDatabaseParameter(HighParam param) throws InvalidInputException { @@ -373,6 +374,12 @@ public class HighFunctionDBUtil { int slot = param.getSlot(); Parameter[] parameters = function.getParameters(); + if (slot < parameters.length) { + if (parameters[slot].isAutoParameter()) { + throw new InvalidInputException( + "Cannot modify auto-parameter: " + parameters[slot].getName()); + } + } if (slot >= parameters.length || !parameters[slot].getVariableStorage().equals(param.getStorage())) { try {