BitFields - updated help screenshots and corrected bitfield conflict

detection issue and structure editor unload/load handling
This commit is contained in:
ghidra1 2019-07-03 14:53:41 -04:00
parent 3f1ffb276f
commit 84a70220dd
10 changed files with 75 additions and 25 deletions

View file

@ -15,24 +15,34 @@
<P>The Structure Editor is used to define the contents of a structure data type. It can be used
to create a new structure or to modify existing ones. Structures are user defined data types
that contain components. A component is a data type of a particular size and at a specified
offset in the structure. The following illustrates the editor for a structure data type.<BR>
offset in the structure. The following illustrates the editor for a structure data type.
</P>
<BR>
<BR>
<DIV align="center" style="margin-top: 10px;">
<IMG src="images/StructureEditor.png" alt=""><BR>
</DIV>
<BR>
<P>As shown above, the Structure Editor also includes a bit-level view of the structure layout to improve
understanding of bitfield placement when they are present. Note that the byte ordering is
reversed for little-endian data organizations to ensure that a bitfield is always rendered
as a contiguous bit range. If inadequate space is available for a component label,
within the bit view of the component, it will be omitted. However, holding down the Shift-key
while using the mouse wheel on a component will zoom the view in and out
allowing component labels to appear when space permits. The bit view may also be used to make
and reflect single component selections with the table. Within the bit view any padding bits not visible within
table view as a component will include a small dot in the center of the displayed bit cell.<BR>
<P>The Union Editor is very similar to the Structure Editor, but is used to create or modify a
union data type. All the components of a Union are at an offset of 0. The following illustrates
the editor for a union data type.</P>
<BR>
<DIV align="center" style="margin-top: 10px;">
<IMG src="images/UnionEditor.png" alt=""><BR>
</DIV>
<BR>
<P>A Structure Editor or Union Editor can be launched from the <A href=
"help/topics/DataTypeManagerPlugin/data_type_manager_description.htm">Data Type Manager</A>,
the <A href="help/topics/CodeBrowserPlugin/CodeBrowser.htm">Code Browser</A>, or the <A href=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

View file

@ -55,11 +55,11 @@ public class BitFieldPlacementComponent extends JPanel {
private int bitWidth = 10;
private int byteWidth = getByteWidth(bitWidth);
private final Composite composite;
private final boolean bigEndian;
private Composite composite;
private boolean bigEndian;
private int allocationByteOffset;
private int allocationByteSize;
private int allocationByteSize = 1;
private BitFieldAllocation bitFieldAllocation;
private EditMode editMode = EditMode.NONE;
@ -114,7 +114,9 @@ public class BitFieldPlacementComponent extends JPanel {
BitFieldPlacementComponent(Composite composite) {
this.composite = composite;
bigEndian = composite.getDataOrganization().isBigEndian();
if (composite != null) {
bigEndian = composite.getDataOrganization().isBigEndian();
}
updatePreferredSize();
setSize(getPreferredSize());
setMinimumSize(getPreferredSize());
@ -122,11 +124,34 @@ public class BitFieldPlacementComponent extends JPanel {
addMouseWheelListener(new MyMouseWheelListener());
}
/**
* Get the composite associated with this component.
* @return composite or null
*/
public Composite getComposite() {
return composite;
}
/**
* Set the current composite. State will reset to a non-edit mode.
* @param composite composite or null
*/
public void setComposite(Composite composite) {
this.composite = composite;
if (composite != null) {
bigEndian = composite.getDataOrganization().isBigEndian();
}
allocationByteOffset = 0;
allocationByteSize = 1;
init(null);
}
private class MyMouseWheelListener implements MouseWheelListener {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getModifiersEx() != InputEvent.SHIFT_DOWN_MASK || e.isConsumed()) {
if (bitFieldAllocation == null || e.getModifiersEx() != InputEvent.SHIFT_DOWN_MASK ||
e.isConsumed()) {
return;
}
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) {
@ -270,6 +295,9 @@ public class BitFieldPlacementComponent extends JPanel {
}
boolean hasApplyConflict() {
if (composite == null || bitFieldAllocation == null) {
throw new IllegalStateException();
}
if (composite instanceof Union) {
return false;
}
@ -316,6 +344,9 @@ public class BitFieldPlacementComponent extends JPanel {
void applyBitField(DataType baseDataType, String fieldName, boolean deleteConflicts,
CompositeChangeListener listener) {
if (composite == null) {
throw new IllegalStateException("Composite not loaded");
}
HashSet<Integer> ordinalDeleteSet = new HashSet<>();
if (editOrdinal >= 0) {
int initialLength = composite.getLength();
@ -732,6 +763,12 @@ public class BitFieldPlacementComponent extends JPanel {
}
private void allocateBits() {
if (composite == null) {
bitAttributes = new BitAttributes[0];
return;
}
bitAttributes = new BitAttributes[8 * allocationByteSize];
if (composite instanceof Structure) {
@ -913,7 +950,8 @@ public class BitFieldPlacementComponent extends JPanel {
// offcut with another component (currently ignored)
c = conflict.conflict;
}
return c != null ? c.dtc : null;
// NOTE: DEFAULT undefined datatype can be ignored as conflict
return c != null && c.dtc.getDataType() != DataType.DEFAULT ? c.dtc : null;
}
void layout(int x, int y, int width, int height) {

View file

@ -21,7 +21,6 @@ import java.awt.dnd.DropTargetDragEvent;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
@ -173,8 +172,18 @@ public class CompEditorPanel extends CompositeEditorPanel {
}
private void update() {
DataTypeComponent dtc = null;
if (!model.isLoaded()) {
bitViewComponent.setComposite(null);
return;
}
if (bitViewComponent.getComposite() != model.viewComposite) {
// must track instance changes caused by model unload/load invocations
bitViewComponent.setComposite(model.viewComposite);
}
bitViewComponent.updateAllocation(model.viewComposite.getLength(), 0);
DataTypeComponent dtc = null;
if (model.isSingleComponentRowSelection()) {
dtc = model.getComponent(model.getSelectedRows()[0]);
}
@ -206,9 +215,9 @@ public class CompEditorPanel extends CompositeEditorPanel {
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(bitViewComponent, BorderLayout.WEST);
p.setBorder(new EmptyBorder(0, 0, 5, 0));
JPanel p = new JPanel();
p.add(bitViewComponent);
//p.setBorder(new EmptyBorder(5, 5, 0, 15));
JScrollPane bitViewScrollPane =
new JScrollPane(p, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
@ -247,7 +256,7 @@ public class CompEditorPanel extends CompositeEditorPanel {
addFieldListeners();
infoPanel.setBorder(BorderFactory.createEmptyBorder(30, 10, 0, 10));
infoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
return infoPanel;
}
@ -267,7 +276,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
nameTextField = new JTextField("");
nameTextField.setToolTipText("Structure Name");
nameTextField.setEditable(true);
nameTextField.setMargin(TEXTFIELD_INSETS);
gridBagConstraints.insets = VERTICAL_INSETS;
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
@ -296,7 +304,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
infoPanel.add(descriptionLabel, gridBagConstraints);
descriptionTextField = new JTextField("");
descriptionTextField.setMargin(TEXTFIELD_INSETS);
descriptionTextField.setToolTipText("Structure Description");
descriptionTextField.setEditable(true);
gridBagConstraints.insets = VERTICAL_INSETS;
@ -329,7 +336,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
categoryStatusTextField = new JTextField(" ");
categoryStatusTextField.setEditable(false);
categoryStatusTextField.setToolTipText("Category of this composite data type.");
categoryStatusTextField.setMargin(TEXTFIELD_INSETS);
gridBagConstraints.insets = VERTICAL_INSETS;
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
@ -499,7 +505,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
minAlignValueTextField.setName("Minimum Alignment Value");
minAlignValueTextField.setEditable(true);
minAlignValueTextField.setMargin(TEXTFIELD_INSETS);
minAlignValueTextField.setToolTipText(alignmentToolTip);
if (helpManager != null) {
helpManager.registerHelp(minAlignValueTextField, new HelpLocation(
@ -575,7 +580,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
}
actualAlignmentValueTextField.setName("Actual Alignment Value");
actualAlignmentValueTextField.setMargin(TEXTFIELD_INSETS);
gridBagConstraints.insets = VERTICAL_INSETS;
gridBagConstraints.anchor = GridBagConstraints.LINE_START;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
@ -676,7 +680,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
packingValueTextField.setName("Packing Value");
packingValueTextField.setEditable(true);
packingValueTextField.setMargin(TEXTFIELD_INSETS);
packingValueTextField.addActionListener(e -> adjustPackingValue());
@ -799,7 +802,6 @@ public class CompEditorPanel extends CompositeEditorPanel {
sizeStatusTextField.setName("Total Length");
sizeStatusTextField.setEditable(false);
sizeStatusTextField.setToolTipText("The current size in bytes.");
sizeStatusTextField.setMargin(TEXTFIELD_INSETS);
gridBagConstraints.ipadx = 60;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.gridx = 1;

View file

@ -72,7 +72,7 @@ public abstract class CompositeEditorPanel extends JPanel
// Normal color for selecting components in the table.
// TODO: Why do we choose a different selection color?
//private static final Color SELECTION_COLOR = Color.YELLOW.brighter().brighter();
protected static final Insets TEXTFIELD_INSETS = new JTextField().getInsets();
//protected static final Insets TEXTFIELD_INSETS = new JTextField().getInsets();
protected static final Border BEVELED_BORDER = BorderFactory.createLoweredBevelBorder();