BitFields - additional refinements and added help content
|
@ -199,6 +199,7 @@ src/main/help/help/topics/DataTypeEditors/images/MultiDuplicateData.png||GHIDRA|
|
|||
src/main/help/help/topics/DataTypeEditors/images/NumDuplicates.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/NumElementsPrompt.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/Plus.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/StructureEditBitfield.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/StructureEditor.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/StructureEditorAligned.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/StructureEditorWithFlexArray.png||GHIDRA||||END|
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
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>
|
||||
and reflect single component selections with the table. Within the bit view any <i>padding</i> bits not visible within
|
||||
the 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
|
||||
|
@ -332,33 +332,36 @@
|
|||
<ul>
|
||||
<li>A bitfield datatype may not exist anywhere other than within a structure or union.</li>
|
||||
<li>A bitfield datatype may not be selected via the datatype chooser or tree since it
|
||||
requires the specification of additional attributes (bit-size, bit-offset, etc.). The
|
||||
bit-size is generally appended to the base-datatype for entry and presentation purposes
|
||||
(e.g., char:1). NOTE: At the API level there is no public or default constructor for the
|
||||
<I>BitFieldDataType</I>. Specific API methods exist for adding bitfields to structures and unions.</li>
|
||||
requires the specification of additional attributes (e.g., bit-size, bit-offset). The
|
||||
bit-size is generally appended to the base-datatype for datatype specification and
|
||||
presentation purposes (e.g., char:1).</li>
|
||||
<li>A zero-length bitfield may be defined within a byte but its' precise bit position
|
||||
is controlled by endianess alone. A zero-length bitfield has no affect within an unaligned
|
||||
structure and is intended for use within aligned structures where it may impart alignment
|
||||
affects based upon compiler conventions.</li>
|
||||
<li>Inserting or moving bitfields may cause component shifts based upon allocation unit
|
||||
byte size and possible placement conflicts.</li>
|
||||
<li>Inserting a bitfield within an unaligned structure may cause component shifts based
|
||||
upon the specified offset and allocation unit byte size when a placement conflict occurs.</li>
|
||||
<li>The start/end byte offsets may be shared with adjacent bitfield components.</li>
|
||||
<li>Unoccupied bits within a partially occupied byte are not represented by any component
|
||||
(similar to padding bytes within aligned structures). Using the bit view provides
|
||||
a precise bit-level view of a component. When a single component is selected, the bit
|
||||
view will highlight the corresponding component block.</li>
|
||||
<li>A separate Bitfield Editor, for use with unaligned structures only,
|
||||
must be used to precisley place a bitfield component. Adding a bitfield component via the
|
||||
structure table view via datatype text entry (e.g., char:1) provides only rough placement.
|
||||
(similar to padding bytes within aligned structures).</li>
|
||||
<li>A separate <a href="#Structure_Bitfield_Editor">Bitfield Editor</a>, for use with unaligned structures only,
|
||||
must be used to precisely place a bitfield component. Adding a bitfield component via the
|
||||
structure table view via datatype text entry (e.g., char:1) provides only rough placement for unaligned
|
||||
structures since additional bytes will be introduced.
|
||||
The BitField Editor may be displayed using the the Add Bitfield and
|
||||
Edit Bitfield popup actions on a selected structure component. The datatype text entry approach
|
||||
must be used for all unions and aligned strctures.</li>
|
||||
Edit Bitfield popup menu actions on a selected structure component. The datatype text entry approach
|
||||
must be used for all unions and aligned structures.</li>
|
||||
</ul>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P><IMG alt="Note:" src="../../shared/note.png">While packing of bitfields within aligned
|
||||
structures is controlled by the compiler specification (e.g., data organization), bit-packing
|
||||
order is currently fixed based upon endianess. Little-endian packs starting with bit-0 (lsb)
|
||||
while big-endian packs starting with bit-7 (msb).</P>
|
||||
|
||||
<P><IMG alt="Note:" src="../../shared/note.png">The use of bitfield components is not
|
||||
currently reflected in decompiler results or assembly markup. </P>
|
||||
|
||||
|
||||
<H2><A name="Structure_Editor_Flex_Array"></A>Flexible Array Component</H2>
|
||||
|
||||
<P>A structure may be defined with a trailing flexible array component which corresponds to
|
||||
|
@ -620,7 +623,35 @@
|
|||
</BLOCKQUOTE><BR>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
<H2><A name="Structure_Editor_Bitfield_Actions"></A>Bitfield Actions (unaligned structures)</H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>The following bitfield actions are available when modifying unaligned structures only and are available
|
||||
via the popup menu based upon a selected component or table row. When working with unions and
|
||||
aligned structures, bitfields may only be specified via datatype text entry specification within the
|
||||
table view (e.g., char:1).</P>
|
||||
|
||||
<H3><A name="Structure_Editor_Add_Bitfield"></A>Add Bitfield</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>With a structure row selected in the vicinity of the desire bitfield placement, the popup
|
||||
menu action (right mouse-click) <B>Add Bitfield</B> may be selected to launch the
|
||||
<a href="#Structure_Bitfield_Editor">Bitfield Editor</a> for a new bitfield.</P>
|
||||
|
||||
<P><IMG alt="Note:" src="../../shared/note.png"> A direct text entry of a bitfield
|
||||
datatype may be specified within the table datatype column (e.g., char:1), although it
|
||||
will always be placed at a default offset.</P>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="Structure_Editor_Edit_Bitfield"></A>Edit Bitfield</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>With a defined bitfield component row selected, the popup
|
||||
menu action (right mouse-click) <B>Edit Bitfield</B> may be selected to launch the
|
||||
<a href="#Structure_Bitfield_Editor">Bitfield Editor</a>.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2><A name="Structure_Editor_Component_Fields"></A>Component Fields</H2>
|
||||
|
||||
<P>Each row displays information about a component in this structure or union. The DataType,
|
||||
|
@ -1218,6 +1249,99 @@
|
|||
<P>To select an option simply click on the check box. <U><BR>
|
||||
</U></P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2><A name="Structure_Bitfield_Editor"></A>Bitfield Editor (unaligned structures only)</H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>The Bitfield Editor is used by the Structure Editor when adding or modifying bitfield components
|
||||
within unaligned structures to facilitate precise placement at the bit level. The Bitfield Editor
|
||||
is not supported for unions and aligned structures since automated packing is performed (i.e.,
|
||||
bitfields are specified via datatype text entry within the structure/union table view).</P>
|
||||
|
||||
<P>The Structure Editor popup menu actions <B>Add Bitfield</B> and <B>Edit Bitfield</B> are
|
||||
used to launch the Bitfield Editor. While the Bitfield Editor is displayed local popup menu actions
|
||||
are provided which can facilitate additional component manipulations (e.g., <B>Add Bitfield</B>,
|
||||
<B>Edit Bitfield</B>, <B>Delete</B>). These actions relate to the component at the current
|
||||
mouse cursor location. Invoking either the <B>Add Bitfield</B> or
|
||||
<B>Edit Bitfield</B> local popup menu actions will immediately cancel the current bitfield
|
||||
operation if one is active.</P>
|
||||
|
||||
<P>The Bitfield Editor includes a visual depiction of the storage allocation bytes and associated
|
||||
bits (8-bits per byte, with a left-toright sequence of 7..0). The displayed byte ordering as
|
||||
conveyed by the <B>Byte Offset</B> header
|
||||
will differ for big-endian vs. little-endian. This is done to ensure that bitfields which span
|
||||
byte boundaries will always visually appear as a consecutive range of bits. The <B>Component Bits</B>
|
||||
display provides both a popup menu and mouse assisted bitfield manipulations. Component labels
|
||||
are included within each component when space permits. The color legend indicates the bit
|
||||
color scheme reflecting Defined bitfields, Defined non-bitfields, Edit bitfield bits, Conflict bits
|
||||
and Undefined bits. A dot in the center of an Undefined bit indicates a padding bit not included
|
||||
within any defined component.</P>
|
||||
|
||||
<BR>
|
||||
<DIV align="center" style="margin-top: 10px;">
|
||||
<IMG src="images/StructureEditBitfield.png" alt=""><BR>
|
||||
</DIV>
|
||||
<BR>
|
||||
|
||||
<P><IMG alt="Tip:" src="../../shared/tip.png"> A component zoom feature is provided which can
|
||||
allow the user to increase the visual bit size allowing for component labels to be shown
|
||||
as size permits. While with the mouse cursor is over a component, use mouse wheel while the
|
||||
Shift key is depressed.</P>
|
||||
|
||||
<H3>Bitfield Parameters</H3>
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<P><B>Structure Offset of Allocation Unit</B> - controls the minimum byte offset of the
|
||||
storage allocation unit represented by the bitfield edit view. This offset is controlled
|
||||
via the <IMG alt="-" src="images/Minus.png"> and
|
||||
<IMG alt="+" src="images/Plus.png"> buttons at the top of the bitfield editor.</P>
|
||||
|
||||
<P><B>Allocation Bytes</B> - controls the size of the storage allocation unit to be utilized
|
||||
in the event a bit conflict exists and the user chooses to <I>Move Conflicts</I>. This numeric
|
||||
entry can be directly entered within the range of 1 through 16 bytes. The mouse wheel may
|
||||
also be used while the cursor is over this entry.</P>
|
||||
|
||||
<P><B>Bit Size</B> - specifies the size of the bitfield in bits. This size may not exceed
|
||||
the size of the specified Base Datatype. This numeric
|
||||
entry can be directly entered or via the mouse wheel while the cursor is over this entry field
|
||||
or the rendered bitfield.</P>
|
||||
|
||||
<P><B>Bit Offset</B> - specifies the offset of the rightmost bit of the bitfield within
|
||||
the displayed allocation unit. This numeric
|
||||
entry can be directly entered or via the mouse wheel while the cursor is over this entry field.</P>
|
||||
|
||||
<P><B>Base Datatype</B> - (required) specifies the numeric datatype associated with the bitfield.
|
||||
Valid datatypes include primitive integer types (e.g., char, int, etc.), enum types, and
|
||||
typedef types of integer or enum types. This input allows direct text input with auto-complete
|
||||
assistance or via full access to a datatype tree chooser by clicking the '...' button.</P>
|
||||
|
||||
<P><B>Field Name</B> - (optional) specifies the structure component name to be assigned to
|
||||
the bitfield. This entry utilizes a simple text entry field.</P>
|
||||
|
||||
<P><IMG alt="Tip:" src="../../shared/tip.png"> The bitfield offset and size may be fully
|
||||
specified by clicking and dragging over the visual bit-range where the bitfield
|
||||
should reside.</P>
|
||||
|
||||
<P><IMG alt="Note:" src="../../shared/note.png"> Within the Bitfield Editor the bit
|
||||
size may not exceed the size of the Base Datatype based upon the structure's
|
||||
associated compiler convention (i.e.,
|
||||
data organization). Since archives use default
|
||||
integer type sizes which may differ from a target program's datatype sizing, the use of fixed-size base
|
||||
datatypes may be preferred. Otherwise, structure edits should be performed within the
|
||||
target program where datatype sizes may be larger. If an existing bitfield size exceeds
|
||||
the size of the base datatype within
|
||||
the associated data organization the "effective" bitfield size will be reduced. As with other
|
||||
components, structure component sizing may change when moving between a datatype archive and
|
||||
a target program.</P>
|
||||
|
||||
<P><IMG alt="Note:" src="../../shared/note.png"> It is important to note that the retained bitfield
|
||||
storage specification (byte offset, component byte size, bit offset) will utilize the smallest possible
|
||||
values while preserving bitfield positioning within the structure. The allocation unit offset and size
|
||||
conveyed by the editor are for editor use only.</P>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P class="providedbyplugin">Provided by: <I>Data Type Manager</I> Plugin</P>
|
||||
|
||||
|
|
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 60 KiB |
|
@ -26,6 +26,7 @@ import docking.action.DockingAction;
|
|||
import docking.action.MenuData;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import resources.ResourceManager;
|
||||
|
||||
public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
|
@ -52,6 +53,8 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
|||
setRememberSize(false);
|
||||
|
||||
addActions();
|
||||
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Bitfield_Editor"));
|
||||
}
|
||||
|
||||
private void addButtons() {
|
||||
|
@ -81,7 +84,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
|||
EditBitFieldAction() {
|
||||
super("Edit Bitfield", "BitFieldEditorDialog");
|
||||
setPopupMenuData(new MenuData(new String[] { getName() }, EDIT_ICON));
|
||||
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Editor_Edit_Bitfield"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,6 +107,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
|||
AddBitFieldAction() {
|
||||
super("Add Bitfield", "BitFieldEditorDialog");
|
||||
setPopupMenuData(new MenuData(new String[] { getName() }, ADD_ICON));
|
||||
setHelpLocation(new HelpLocation("DataTypeEditors", "Structure_Editor_Add_Bitfield"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,7 +133,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
|||
private class DeleteComponentAction extends DockingAction {
|
||||
|
||||
DeleteComponentAction() {
|
||||
super("Delete Component", "BitFieldEditorDialog");
|
||||
super("Delete", "BitFieldEditorDialog");
|
||||
setPopupMenuData(new MenuData(new String[] { getName() }, DELETE_ICON));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.awt.*;
|
|||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.CellEditorListener;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
|
||||
|
@ -274,13 +273,15 @@ public class BitFieldEditorPanel extends JPanel {
|
|||
if (e.isConsumed()) {
|
||||
return;
|
||||
}
|
||||
e.consume();
|
||||
selectionActive = false;
|
||||
if (e.getButton() == MouseEvent.BUTTON1 && bitOffsetInput.isEnabled()) {
|
||||
bitSizeModel.setValue(1L); // must change size first
|
||||
startBit = setBitFieldOffset(e.getPoint());
|
||||
lastBit = startBit;
|
||||
selectionActive = startBit >= 0;
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
e.consume();
|
||||
selectionActive = false;
|
||||
if (bitOffsetInput.isEnabled()) {
|
||||
bitSizeModel.setValue(1L); // must change size first
|
||||
startBit = setBitFieldOffset(e.getPoint());
|
||||
lastBit = startBit;
|
||||
selectionActive = startBit >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,15 +330,6 @@ public class BitFieldEditorPanel extends JPanel {
|
|||
}
|
||||
|
||||
private JPanel createPlacementPanel() {
|
||||
JPanel midPanel = new JPanel(new PairLayout(5, 5));
|
||||
|
||||
JPanel leftMidPanel = new JPanel(new VerticalLayout(13));
|
||||
leftMidPanel.setBorder(BorderFactory.createEmptyBorder(12, 8, 12, 0));
|
||||
JLabel byteOffsetLabel = new JLabel("Byte Offset:", SwingConstants.RIGHT);
|
||||
byteOffsetLabel.setToolTipText("Byte Offset is relative to start of allocation unit");
|
||||
leftMidPanel.add(byteOffsetLabel);
|
||||
leftMidPanel.add(new JLabel("Bits:", SwingConstants.RIGHT));
|
||||
midPanel.add(leftMidPanel);
|
||||
|
||||
placementComponent = new BitFieldPlacementComponent(composite);
|
||||
placementComponent.setFont(UIManager.getFont("TextField.font"));
|
||||
|
@ -347,17 +339,23 @@ public class BitFieldEditorPanel extends JPanel {
|
|||
placementComponent.addMouseListener(bitSelectionHandler);
|
||||
placementComponent.addMouseMotionListener(bitSelectionHandler);
|
||||
|
||||
JPanel p = new JPanel(new BorderLayout());
|
||||
p.add(placementComponent, BorderLayout.WEST);
|
||||
p.setBorder(new EmptyBorder(0, 0, 5, 0));
|
||||
JPanel bitViewPanel = new JPanel(new PairLayout(0, 5));
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(p, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
JPanel labelPanel = new JPanel(new VerticalLayout(7));
|
||||
labelPanel.setBorder(BorderFactory.createEmptyBorder(7, 5, 0, 0));
|
||||
JLabel byteOffsetLabel = new JLabel("Byte Offset:", SwingConstants.RIGHT);
|
||||
labelPanel.add(byteOffsetLabel);
|
||||
labelPanel.add(new JLabel("Component Bits:", SwingConstants.RIGHT));
|
||||
bitViewPanel.add(labelPanel);
|
||||
|
||||
JScrollPane scrollPane =
|
||||
new JScrollPane(placementComponent, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
scrollPane.getViewport().setBackground(getBackground());
|
||||
scrollPane.setBorder(null);
|
||||
|
||||
midPanel.add(scrollPane);
|
||||
return midPanel;
|
||||
bitViewPanel.add(scrollPane);
|
||||
return bitViewPanel;
|
||||
}
|
||||
|
||||
private boolean checkValidBaseDataType() {
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.swing.*;
|
|||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Composite;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
|
@ -37,7 +38,7 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
private static final int BIT_SEPARATOR_THICKNESS = 1;
|
||||
private static final int BYTE_SEPARATOR_THICKNESS = 2;
|
||||
// private static final int BYTE_WIDTHx = 8 * (BIT_WIDTH + BIT_SEPARATOR_THICKNESS);
|
||||
private static final int SCROLLBAR_THICKNESS = 10;
|
||||
private static final int SCROLLBAR_THICKNESS = 15;
|
||||
private static final int MY_HEIGHT = (2 * CELL_HEIGHT) + (3 * BYTE_SEPARATOR_THICKNESS);
|
||||
|
||||
private static final int LENEND_BOX_SIZE = 16;
|
||||
|
@ -476,8 +477,14 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
@Override
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
BitAttributes attrs = getBitAttributes(e.getPoint());
|
||||
String dtcInfo = attrs != null ? (attrs.getTip() + "<BR>") : "";
|
||||
return "<HTML><div style=\"text-align:center\">" + dtcInfo +
|
||||
if (attrs == null) {
|
||||
return null;
|
||||
}
|
||||
String tip = attrs.getTip();
|
||||
if (tip == null) {
|
||||
return null;
|
||||
}
|
||||
return "<HTML><div style=\"text-align:center\">" + HTMLUtilities.escapeHTML(tip) +
|
||||
"<div style=\"color: gray;font-style: italic\">(Shift-wheel to zoom)</div></div></HTML>";
|
||||
|
||||
}
|
||||
|
@ -930,19 +937,19 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
boolean isAddBitField() {
|
||||
private boolean isAddBitField() {
|
||||
return !unallocated && dtc == null;
|
||||
}
|
||||
|
||||
boolean isEditField() {
|
||||
private boolean isEditField() {
|
||||
return dtc != null && dtc.getOrdinal() == editOrdinal;
|
||||
}
|
||||
|
||||
boolean hasConflict() {
|
||||
private boolean hasConflict() {
|
||||
return getConflict() != null;
|
||||
}
|
||||
|
||||
public DataTypeComponent getConflict() {
|
||||
private DataTypeComponent getConflict() {
|
||||
BitAttributes c = conflict;
|
||||
while (c != null && c.dtc.isZeroBitFieldComponent()) {
|
||||
// TODO: improve conflict detection
|
||||
|
@ -961,7 +968,7 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
void paint(Graphics g, BitAttributes bitAttrsToLeft, boolean paintRightLine) {
|
||||
private void paint(Graphics g, BitAttributes bitAttrsToLeft, boolean paintRightLine) {
|
||||
// bit box
|
||||
Color c = getColor();
|
||||
g.setColor(c);
|
||||
|
@ -1017,7 +1024,7 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
Color getColor() {
|
||||
private Color getColor() {
|
||||
if (unallocated) {
|
||||
return UNDEFINED_BIT_COLOR;
|
||||
}
|
||||
|
@ -1035,7 +1042,10 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
: NON_BITFIELD_COMPONENT_COLOR;
|
||||
}
|
||||
|
||||
String getTip() {
|
||||
private String getTip() {
|
||||
if (unallocated) {
|
||||
return "<padding>";
|
||||
}
|
||||
if (dtc == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import ghidra.program.model.data.Composite.AlignmentType;
|
|||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
|
||||
/**
|
||||
* Panel for editing a composite with a blank line at the bottom of the table
|
||||
|
@ -215,19 +217,24 @@ public class CompEditorPanel extends CompositeEditorPanel {
|
|||
}
|
||||
});
|
||||
|
||||
JPanel p = new JPanel();
|
||||
p.add(bitViewComponent);
|
||||
//p.setBorder(new EmptyBorder(5, 5, 0, 15));
|
||||
JPanel bitViewPanel = new JPanel(new PairLayout(0, 5));
|
||||
|
||||
JPanel labelPanel = new JPanel(new VerticalLayout(7));
|
||||
labelPanel.setBorder(BorderFactory.createEmptyBorder(7, 5, 0, 0));
|
||||
JLabel byteOffsetLabel = new JLabel("Byte Offset:", SwingConstants.RIGHT);
|
||||
labelPanel.add(byteOffsetLabel);
|
||||
labelPanel.add(new JLabel("Component Bits:", SwingConstants.RIGHT));
|
||||
bitViewPanel.add(labelPanel);
|
||||
|
||||
JScrollPane bitViewScrollPane =
|
||||
new JScrollPane(p, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||
new JScrollPane(bitViewComponent, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
|
||||
bitViewScrollPane.getViewport().setBackground(getBackground());
|
||||
bitViewScrollPane.setBorder(null);
|
||||
|
||||
JPanel bitViewerPanel = new JPanel(new BorderLayout());
|
||||
bitViewerPanel.add(bitViewScrollPane, BorderLayout.CENTER);
|
||||
return bitViewerPanel;
|
||||
bitViewPanel.add(bitViewScrollPane);
|
||||
return bitViewPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,7 +101,7 @@ public class BytesFieldFactory extends FieldFactory {
|
|||
fieldOptions.registerOption(REVERSE_INSTRUCTION_BYTE_ORDERING, false, hl,
|
||||
"Reverses the normal order of the bytes in the bytes field." +
|
||||
" Only used for instructions in Little Endian format");
|
||||
fieldOptions.registerOption(DISPLAY_STRUCTURE_ALIGNMENT_BYTES_MSG, false, hl,
|
||||
fieldOptions.registerOption(DISPLAY_STRUCTURE_ALIGNMENT_BYTES_MSG, true, hl,
|
||||
"Display trailing alignment bytes in structures.");
|
||||
|
||||
delim = fieldOptions.getString(DELIMITER_MSG, " ");
|
||||
|
|
|
@ -229,7 +229,7 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
@Test
|
||||
public void testStructureEditorAligned() {
|
||||
|
||||
createAlignedDetailedStructure(0x40d2b8, false);
|
||||
createDetailedStructure(0x40d2b8, true, false);
|
||||
|
||||
goToListing(0x40d2b8, true);
|
||||
|
||||
|
@ -241,7 +241,7 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
@Test
|
||||
public void testStructureEditorWithFlexArray() {
|
||||
|
||||
createAlignedDetailedStructure(0x40d2b8, true);
|
||||
createDetailedStructure(0x40d2b8, true, true);
|
||||
|
||||
goToListing(0x40d2b8, true);
|
||||
|
||||
|
@ -250,6 +250,29 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
captureProvider(StructureEditorProvider.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructureEditBitfield() {
|
||||
|
||||
createDetailedStructure(0x40d2b8, false, true);
|
||||
|
||||
goToListing(0x40d2b8, true);
|
||||
|
||||
performAction("Edit Data Type", "DataPlugin", true);
|
||||
|
||||
ComponentProvider structureEditor = getProvider(StructureEditorProvider.class);
|
||||
|
||||
// get structure table and select a row
|
||||
CompositeEditorPanel editorPanel =
|
||||
(CompositeEditorPanel) getInstanceField("editorPanel", structureEditor);
|
||||
JTable table = editorPanel.getTable();
|
||||
selectRow(table, 4); // select byte:3 bitfield
|
||||
|
||||
performAction("Editor: Edit Bitfield", "DataTypeManagerPlugin", structureEditor, false);
|
||||
waitForSwing();
|
||||
|
||||
captureDialog();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionEditor() {
|
||||
|
||||
|
@ -295,12 +318,13 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
waitForBusyTool(tool);
|
||||
}
|
||||
|
||||
private void createAlignedDetailedStructure(long address,
|
||||
private void createDetailedStructure(long address, boolean aligned,
|
||||
boolean includeBitFieldsAndFlexArray) {
|
||||
|
||||
goToListing(address);
|
||||
|
||||
StructureDataType struct = new StructureDataType("MyAlignedStruct", 0);
|
||||
struct.setInternallyAligned(true); // allow proper default packing
|
||||
struct.add(new ByteDataType(), "myByteElement", "alignment 1");
|
||||
struct.add(new ByteDataType(), "", "This is my undefined element");
|
||||
struct.add(new WordDataType(), "myWordElement", "alignment 2");
|
||||
|
@ -325,7 +349,7 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator {
|
|||
(includeBitFieldsAndFlexArray ? "with bitfields and a flexible char array"
|
||||
: "according to their alignment size") +
|
||||
". ");
|
||||
struct.setInternallyAligned(true);
|
||||
struct.setInternallyAligned(aligned);
|
||||
|
||||
CreateDataCmd createDataCmd = new CreateDataCmd(addr(address), struct);
|
||||
tool.execute(createDataCmd, program);
|
||||
|
|