GP-862 Refactor of Composite interface and internals. Changes made to
packing and alignment methods (see WhatsNew.html for API changes).
@@ -344,7 +344,7 @@
|
||||
<ul>
|
||||
<li><I>Data Types</I>. Improved PDB composite reconstruction to attempt <code>pack(1)</code> alignment if default alignment fails. (GT-3401)</li>
|
||||
<li><I>Data Types</I>. Added missing support for multi-user merge of unions and structures containing bitfields or a trailing flexible array member. (GT-3479)</li>
|
||||
<li><I>Data Types</I>. Corrected structure editor save button enablement issue when editing bitfields within an unaligned structure. (GT-3519, Issue #1297)</li>
|
||||
<li><I>Data Types</I>. Corrected structure editor save button enablement issue when editing bitfields within a non-packed structure. (GT-3519, Issue #1297)</li>
|
||||
<li><I>Disassembly</I>. Corrected potential infinite loop with disassembler caused by branch to self with invalid delay slot instruction. (GT-3511, Issue #1486)</li>
|
||||
<li><I>GUI</I>. Corrected processor manual display for Microsoft Windows users, which was not displaying processor manual and was, instead, rendering a blank page in web browser. (GT-3444)</li>
|
||||
<li><I>GUI:Bitfield Editor</I>. Added field comment support to composite bitfield editor. (GT-3410)</li>
|
||||
@@ -393,7 +393,7 @@
|
||||
<H1 align="center">Ghidra 9.1 Change History (October 2019)</H1>
|
||||
<blockquote><p><u>New Features</u></p>
|
||||
<ul>
|
||||
<li><I>Data Types</I>. Added bit-field support to Structure and Union editor. An additional Bit-field Editor was also added for explicit bit-field placement within unaligned structures. (GT-559)</li>
|
||||
<li><I>Data Types</I>. Added bit-field support to Structure and Union editor. An additional Bit-field Editor was also added for explicit bit-field placement within non-packed structures. (GT-559)</li>
|
||||
<li><I>Eclipse Integration</I>. Added new GhidraSleighEditor Eclipse plugin in the installation directory under Extensions/Eclipse. (GT-113)</li>
|
||||
<li><I>GUI</I>. Added method for turning off table sorting by control-clicking the only sorted table column. (GT-2763, Issue #87)</li>
|
||||
<li><I>GUI</I>. Hovering on an address will now show where the byte at that address came from in the imported file. (GT-3016, Issue #154)</li>
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
li { font-family:times new roman; font-size:14pt; font-family:times new roman; font-size:14pt; margin-bottom: 8px; }
|
||||
h1 { color:#000080; font-family:times new roman; font-size:28pt; font-style:italic; font-weight:bold; text-align:center; color:#000080; font-family:times new roman; }
|
||||
h2 { padding-top:20px; color:#984c4c; font-family:times new roman; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
|
||||
h3 { margin-left:40px; padding-top:10px; font-family:times new roman; font-family:times new roman; font-size:14pt; font-weight:bold; }
|
||||
p { margin-left:40px; font-family:times new roman; font-size:14pt; }
|
||||
td { font-family:times new roman; font-size:14pt; padding-left:10px; padding-right:14px; }
|
||||
th { font-family:times new roman; font-size:14pt; font-weight:bold; padding-left:10px; padding-right:14px; }
|
||||
code { color:black; font-family:courier new font-size: 14pt; }
|
||||
table, th, td { border: 1px solid black; border-collapse: collapse; font-size:10pt; }
|
||||
td { font-family:times new roman; font-size:14pt; padding-left:10px; padding-right:10px; text-align:left; vertical-align:top; }
|
||||
th { font-family:times new roman; font-size:14pt; font-weight:bold; padding-left:10px; padding-right:10px; text-align:left; }
|
||||
code { color:black; font-family:courier new; font-size: 12pt; }
|
||||
span.code { font-family:courier new font-size: 14pt; color:#000000; }
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
@@ -39,6 +41,145 @@
|
||||
vulnerabilities in networks and systems.
|
||||
</P>
|
||||
|
||||
<BR />
|
||||
<H1> What's New in Ghidra 10.0</H1>
|
||||
|
||||
<H2>Debugger</H2>
|
||||
|
||||
<P>Stay tuned...
|
||||
|
||||
<H2>Structure/Union Changes</H2>
|
||||
|
||||
<P>A significant refactor of the Composite datatype interfaces and internals has been completed which affects
|
||||
Structures and Unions. The intent of these changes was to provide a more unstandable API and allow an alignment
|
||||
to be specified for non-packed composites (aka, composites with internal alignment disabled).</P>
|
||||
|
||||
<H3>Editor Changes</H3>
|
||||
|
||||
<P>Previously, the editor contained an <B>Align</B> checkbox which determined if packing should be performed or not.
|
||||
This checkbox has been replaced by a checkbox adjacent to the <B>pack</B> choices (i.e., enable/disable packing).
|
||||
Generally, this setting would be "not-checked" (i.e., disabled) when reverse-engineering the content of a
|
||||
structure so that components may be placed at specific offsets. Only when there is a complete understanding
|
||||
of all components, as conveyed by a source header file, should
|
||||
this be enabled with the appropriate <B>pack</B> and <B>align</B> settings specified. In addition, when <B>pack</B>
|
||||
is enabled it is important that the component datatypes eimit the correct alignment to ensure proper
|
||||
placement during packing.</P>
|
||||
|
||||
<P>The <B>align</B> setting may know be used when packing is disabled with the composite adopting
|
||||
the specified alignment. The default alignment for a non-packed composite is <B>1</B> which is consistent
|
||||
with the current behavior in Ghidra 9.x.</P>
|
||||
|
||||
<H3>Composite API Changes</H3>
|
||||
|
||||
<P>The various pack and align methods of the <I>Composite</I> (i.e., <I>Structure</I> and <I>Union</I>)
|
||||
API have been changed extensively. Since these changes were primarly intended to "cleanup" the
|
||||
interface it was decided not eliminate (not depricate) the old methods. It was felt leaving them in
|
||||
place would only confuse matters when attempting to understand the new interface. It is also believed that
|
||||
most uses of the API generally do not utilize the pack and align settings which should minimize the
|
||||
impact to existing user code.<P>
|
||||
|
||||
<P>The tables below convey the <I>Composite</I> API changes as they relate to the pack and align settings.</P>
|
||||
<BLOCKQUOTE>
|
||||
<P>
|
||||
<TABLE WIDTH="100%">
|
||||
<TR>
|
||||
<TD COLSPAN="3" padding-top:14px; padding-bottom:14px;><CENTER><B>Composite Pack API Changes</B></CENTER></TD>
|
||||
</TR><TR style="background-color:#DFDFDF;">
|
||||
<TH>Old Method 9.x</TH><TH>New Method 10.0</TH><TH>Comments</TH>
|
||||
</TR><TR>
|
||||
<TD><CODE>setInternallyAligned(<font color="blue">boolean</font>)</CODE></TD>
|
||||
<TD><CODE>setPackingEnabled(<font color="blue">boolean</font>)</CODE></TD>
|
||||
<TD> </TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>isInternallyAligned()</CODE></TD>
|
||||
<TD><CODE>isPackingEnabled()</CODE></TD>
|
||||
<TD>Equivalent to: <CODE>getPackingType() != DISABLED</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>setPackingValue(NOT_PACKING)<BR>setPackingValue(1..n)</CODE></TD>
|
||||
<TD><CODE>setToDefaultPacking()<BR>setExplicitPackingValue(1..n)<BR>pack(1..n)</CODE></TD>
|
||||
<TD>Packing will be enabled if not previously enabled. Old constant <CODE>NOT_PACKING</CODE> has been elliminated.</TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>getPackingValue()</CODE></TD>
|
||||
<TD><CODE>getExplicitPackingValue()</CODE></TD>
|
||||
<TD>New method use does not directly map (see Javadocs). Old constant <CODE>NOT_PACKING</CODE> has been elliminated.</TD>
|
||||
</TR><TR>
|
||||
<TD> </TD>
|
||||
<TD><CODE>hasDefaultPacking()</CODE></TD>
|
||||
<TD>Equivalent to: <CODE>getPackingType() == DEFAULT</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD> </TD>
|
||||
<TD><CODE>hasExplicitPackingValue()</TD>
|
||||
<TD>Equivalent to: <CODE>getPackingType() == EXPLICIT</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD> </TD>
|
||||
<TD><CODE>getPackingType()</TD>
|
||||
<TD>Possible values: <CODE>DISABLED</CODE>, <CODE>DEFAULT</CODE> or <CODE>EXPLICIT</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>realign()</CODE></TD>
|
||||
<TD><CODE>repack()</CODE></TD>
|
||||
<TD>Update component sizing and placement if composite has packing enabled.
|
||||
Changes to data organization (e.g., type sizes and alignments) are problematic and difficult to fully
|
||||
recover from. Any attempted repair to component sizes and alignments need to be performed in
|
||||
dependency order (ignoring pointer components).</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
<TABLE WIDTH="100%">
|
||||
<TR>
|
||||
<TD COLSPAN="3"><CENTER><B>Composite Align API Changes</B></CENTER><BR>
|
||||
<B>NOTE!</B> The old alignment <I>set</I> methods previously forced packing to be enabled.
|
||||
This is no longer the case since the alignment setting is now supported for composites
|
||||
where packing is not enabled. If packing should be enabled a separate
|
||||
call to a packing enablement method (see above) is required. When packing is <U>disabled</U>
|
||||
the composite's computed alignment will match the specified align setting (default is
|
||||
1 which is consistent with old behavior).
|
||||
</TD>
|
||||
</TR><TR style="background-color:#DFDFDF;">
|
||||
<TH>Old Method 9.x</TH><TH>New Method 10.0</TH><TH>Comments</TH>
|
||||
</TR><TR>
|
||||
<TD><CODE>setToDefaultAlignment()</CODE></TD>
|
||||
<TD><CODE>setToDefaultAligned()</CODE></TD>
|
||||
<TD>Default alignment for a non-packed composite is 1. When packing is enabled the
|
||||
default alignment is a function of the component packing.</TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>isDefaultAligned()</CODE></TD>
|
||||
<TD><CODE>isDefaultAligned()</CODE></TD>
|
||||
<TD>Equivalent to: <CODE>getAlignmentType() == DEFAULT</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>setToMachineAlignment()</CODE></TD>
|
||||
<TD><CODE>setToMachineAligned()</CODE></TD>
|
||||
<TD>Non-packed composites will have an alignment which equals the machine alignment
|
||||
specified by the compiler specification (data organization). Packed structures
|
||||
will have an alignment which is a multiple of the machine alignment.</TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>isMachineAligned()</CODE></TD>
|
||||
<TD><CODE>isMachineAligned()</CODE></TD>
|
||||
<TD>Equivalent to: <CODE>getAlignmentType() == MACHINE</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>setMinimumAlignment(DEFAULT_ALIGNMENT_VALUE)<BR>setMinimumAlignment(1..n)</CODE></TD>
|
||||
<TD><CODE>setToDefaultAligned()<BR>setExplicitMinimumAlignment(1..n)<BR>align(1..n)</CODE></TD>
|
||||
<TD>
|
||||
If an explicit minimum alignment is set (1..n), non-packed composites will have an alignment
|
||||
which equals this value, while packed structures
|
||||
will have an alignment which is a multiple of this value.
|
||||
Old constant <CODE>DEFAULT_ALIGNMENT_VALUE</CODE> has been elliminated.
|
||||
</TD>
|
||||
</TR><TR>
|
||||
<TD><CODE>getMinimumAlignment()</CODE></TD>
|
||||
<TD><CODE>getExplicitMinimumAlignment()</CODE></TD>
|
||||
<TD>New method use does not directly map (see Javadocs). Old constant <CODE>DEFAULT_ALIGNMENT_VALUE</CODE> has been elliminated.</TD>
|
||||
</TR><TR>
|
||||
<TD></TD>
|
||||
<TD><CODE>hasExplicitMinimumAlignment()</CODE></TD>
|
||||
<TD>Equivalent to: <CODE>getAlignmentType() == EXPLICIT</CODE></TD>
|
||||
</TR><TR>
|
||||
<TD></TD>
|
||||
<TD><CODE>getAlignmentType()</CODE></TD>
|
||||
<TD>Possible values: <CODE>DEFAULT, MACHINE or EXPLICIT</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<BR />
|
||||
<H1> What's New in Ghidra 9.2</H1>
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ public class DBTraceDataTypeManager extends DataTypeManagerDB
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dataTypeChanged(DataType dataType) {
|
||||
super.dataTypeChanged(dataType);
|
||||
public void dataTypeChanged(DataType dataType, boolean isAutoChange) {
|
||||
super.dataTypeChanged(dataType, isAutoChange);
|
||||
if (!isCreatingDataType()) {
|
||||
trace.getCodeManager().invalidateCache(false);
|
||||
trace.getSymbolManager().invalidateCache(false);
|
||||
|
||||
@@ -203,10 +203,10 @@ src/main/help/help/topics/DataTypeEditors/images/NumElementsPrompt.png||GHIDRA||
|
||||
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/StructureEditorPacked.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/StructureEditorWithFlexArray.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/UnionEditor.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/UnionEditorAligned.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/UnionEditorPacked.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/Unpackage.gif||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/cstruct.png||GHIDRA||reviewed||END|
|
||||
src/main/help/help/topics/DataTypeEditors/images/disk.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
|
||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -487,14 +487,13 @@
|
||||
Archive</B></I> action.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="Align_All_Data_Types"></A>Aligning All Data Types In a Program or Archive</H3>
|
||||
<H3><A name="Pack_All_Data_Types"></A>Pack All Data Types In a Program or Archive</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>Right-click on the program or data type archive where data types are to be aligned,
|
||||
and select the <I><B>Align All...</B></I> action. A confirmation dialog will appear to
|
||||
make sure you want to align all the structures and unions in the program or data type
|
||||
archive. If you continue, all structures and unions that are unaligned will be changed to
|
||||
aligned data types with no minimum alignment (the default) and no packing.</P>
|
||||
<P>Right-click on the program or data type archive where structures and unions are to be packed,
|
||||
and select the <I><B>Pack All...</B></I> action. A confirmation dialog will appear to
|
||||
make sure you want to pack all composites in the program or data type
|
||||
archive. If you continue, all non-packed composites will have default packing enabled.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="synchronizing"></A> <A name="Update"></A> Updating an Archive From a Source
|
||||
@@ -926,15 +925,14 @@
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<!-- disabled feature
|
||||
<H3><A name="Align_Data_Type"></A>Aligning a Data Type</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>Right-click on the structure or union to be aligned. Select the <I><B>Align</B></I>
|
||||
action. If the data type is unaligned it will be changed to an aligned data type with no
|
||||
minimum alignment (the default) and no packing.</P>
|
||||
<P>Right-click on the structure or union to be packed. Select the <I><B>Pack</B></I>
|
||||
action. If the data type is non-packed it will be changed to be default packed.</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
-->
|
||||
<H3><A name="Commit_To_Archive"></A>Committing Changes To Source Archive</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
@@ -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.
|
||||
@@ -103,7 +102,7 @@ public class CreateArrayInStructureCmd implements Command {
|
||||
try {
|
||||
ArrayDataType adt = new ArrayDataType(dataType, numElements, dataType.getLength());
|
||||
clearStruct(struct, compData.getParentOffset(), length);
|
||||
if (struct.isInternallyAligned()) {
|
||||
if (struct.isPackingEnabled()) {
|
||||
struct.insert(index, adt, adt.getLength());
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1164,7 +1164,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
updateAlignment(sourceDt, destStruct);
|
||||
|
||||
DataTypeManager sourceDTM = sourceDt.getDataTypeManager();
|
||||
boolean aligned = sourceDt.isInternallyAligned();
|
||||
boolean aligned = sourceDt.isPackingEnabled();
|
||||
|
||||
// Add each of the defined components back in.
|
||||
DataTypeComponent[] comps = sourceDt.getDefinedComponents();
|
||||
@@ -1480,17 +1480,25 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
|
||||
private void updateAlignment(Composite sourceDt, Composite destinationDt) {
|
||||
if (sourceDt.isDefaultAligned()) {
|
||||
destinationDt.setToDefaultAlignment();
|
||||
destinationDt.setToDefaultAligned();
|
||||
}
|
||||
else if (sourceDt.isMachineAligned()) {
|
||||
destinationDt.setToMachineAlignment();
|
||||
destinationDt.setToMachineAligned();
|
||||
}
|
||||
else {
|
||||
destinationDt.setMinimumAlignment(sourceDt.getMinimumAlignment());
|
||||
destinationDt.setExplicitMinimumAlignment(sourceDt.getExplicitMinimumAlignment());
|
||||
}
|
||||
if (sourceDt.isPackingEnabled()) {
|
||||
if (sourceDt.hasExplicitPackingValue()) {
|
||||
destinationDt.setExplicitPackingValue(sourceDt.getExplicitPackingValue());
|
||||
}
|
||||
else {
|
||||
destinationDt.setToDefaultPacking();
|
||||
}
|
||||
}
|
||||
else {
|
||||
destinationDt.setPackingEnabled(false);
|
||||
}
|
||||
destinationDt.setPackingValue(sourceDt.getPackingValue());
|
||||
boolean aligned = sourceDt.isInternallyAligned();
|
||||
destinationDt.setInternallyAligned(aligned);
|
||||
}
|
||||
|
||||
private void updateComposite(long sourceDtID, Composite sourceDt, Composite destDt,
|
||||
@@ -1860,11 +1868,15 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
private boolean compositeDataTypeWasChanged(Composite c1, Composite c2) {
|
||||
DataTypeManager dtm1 = c1.getDataTypeManager();
|
||||
DataTypeManager dtm2 = c2.getDataTypeManager();
|
||||
if (c1.isInternallyAligned() != c2.isInternallyAligned() ||
|
||||
c1.isDefaultAligned() != c2.isDefaultAligned() ||
|
||||
c1.isMachineAligned() != c2.isMachineAligned() ||
|
||||
c1.getMinimumAlignment() != c2.getMinimumAlignment() ||
|
||||
c1.getPackingValue() != c2.getPackingValue()) {
|
||||
|
||||
PackingType packingType = c1.getPackingType();
|
||||
AlignmentType alignmentType = c1.getAlignmentType();
|
||||
|
||||
if ((packingType != c2.getPackingType()) || (alignmentType != c2.getAlignmentType()) ||
|
||||
(packingType == PackingType.EXPLICIT &&
|
||||
c1.getExplicitPackingValue() != c2.getExplicitPackingValue()) ||
|
||||
(alignmentType == AlignmentType.EXPLICIT &&
|
||||
c1.getExplicitMinimumAlignment() != c2.getExplicitMinimumAlignment())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1877,7 +1889,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
boolean checkOffsets = false;
|
||||
|
||||
if (c1 instanceof Structure) {
|
||||
if (!((Structure) c1).isInternallyAligned()) {
|
||||
if (!((Structure) c1).isPackingEnabled()) {
|
||||
if (c1.getNumComponents() != c2.getNumComponents()) {
|
||||
return true;
|
||||
}
|
||||
@@ -2444,13 +2456,13 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process fixup for unaligned structure component
|
||||
* Process fixup for non-packed structure component
|
||||
* @param info fixup info
|
||||
* @param struct result structure
|
||||
* @param dt component datatype
|
||||
* @return false if component not found, else true
|
||||
*/
|
||||
private boolean fixUpUnalignedStructureComponent(FixUpInfo info, Structure struct,
|
||||
private boolean fixUpNonPackedStructureComponent(FixUpInfo info, Structure struct,
|
||||
DataType dt) {
|
||||
int offset = info.index;
|
||||
DataTypeComponent dtc = struct.getComponentAt(offset);
|
||||
@@ -2533,7 +2545,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
boolean isFlexArrayFixup = (info.index == Integer.MAX_VALUE);
|
||||
|
||||
if (compDt != null) {
|
||||
if (struct.isInternallyAligned() || isFlexArrayFixup) {
|
||||
if (struct.isPackingEnabled() || isFlexArrayFixup) {
|
||||
if (!fixUpAlignedStructureComponent(info, struct, compDt)) {
|
||||
String msg =
|
||||
isFlexArrayFixup ? "flex-array component" : ("component " + info.index);
|
||||
@@ -2544,7 +2556,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fixUpUnalignedStructureComponent(info, struct, compDt)) {
|
||||
if (!fixUpNonPackedStructureComponent(info, struct, compDt)) {
|
||||
Msg.warn(this, "Structure Merge: Couldn't get component at offset " +
|
||||
info.index + " in " + struct.getPathName());
|
||||
return false;
|
||||
@@ -2556,7 +2568,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
else if (isFlexArrayFixup) {
|
||||
struct.clearFlexibleArrayComponent();
|
||||
}
|
||||
else if (struct.isInternallyAligned()) {
|
||||
else if (struct.isPackingEnabled()) {
|
||||
int ordinal = info.index;
|
||||
int numComponents = struct.getNumComponents();
|
||||
if (ordinal >= 0 && ordinal < numComponents) {
|
||||
@@ -2595,7 +2607,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
* @return the number of contiguous undefined bytes or 0.
|
||||
*/
|
||||
private int getNumUndefinedBytes(Structure struct, int ordinal) {
|
||||
if (struct.isInternallyAligned()) {
|
||||
if (struct.isPackingEnabled()) {
|
||||
return 0;
|
||||
}
|
||||
int numComponents = struct.getNumComponents();
|
||||
@@ -3276,7 +3288,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
|
||||
private static int getComponentFixupIndex(DataTypeComponent dtc) {
|
||||
Composite composite = (Composite) dtc.getParent();
|
||||
if (composite.isInternallyAligned() || (composite instanceof Union)) {
|
||||
if (composite.isPackingEnabled() || (composite instanceof Union)) {
|
||||
return dtc.getOrdinal();
|
||||
}
|
||||
return dtc.getOffset();
|
||||
@@ -3301,7 +3313,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
* or components were resolved.
|
||||
* @param id id of data type needed to be fixed up
|
||||
* @param compID id of either component or base type
|
||||
* @param index offset into unaligned structure, or ordinal into union or aligned
|
||||
* @param index offset into non-packed structure, or ordinal into union or packed
|
||||
* structure; or parameter/return ordinal; for other data types index is not used (specify -1).
|
||||
* For structure trailing flex-array specify {@link Integer#MAX_VALUE}.
|
||||
* @param resolvedDataTypes hashtable used for resolving the data type
|
||||
@@ -3333,7 +3345,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find unaligned structure bitfield component at or after specified component
|
||||
* Find non-packed structure bitfield component at or after specified component
|
||||
* which matches this info's bitfield data.
|
||||
* @param struct structure
|
||||
* @param dtc structure component contained within struct
|
||||
@@ -3412,7 +3424,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param index offset into unaligned structure, or ordinal into union or aligned
|
||||
* @param index offset into non-packed structure, or ordinal into union or packed
|
||||
* structure; for other data types, offset is not used (specify -1)
|
||||
* @param resolvedDataTypes hashtable used for resolving the data type
|
||||
*/
|
||||
@@ -3466,7 +3478,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||
}
|
||||
|
||||
private void cleanUpStructure(int[] indexArray, Structure dt) {
|
||||
boolean aligned = dt.isInternallyAligned();
|
||||
boolean aligned = dt.isPackingEnabled();
|
||||
Arrays.sort(indexArray);
|
||||
for (int i = indexArray.length - 1; i >= 0; i--) {
|
||||
if (aligned) {
|
||||
|
||||
@@ -149,28 +149,8 @@ class DataTypePanel extends JPanel {
|
||||
}
|
||||
|
||||
private void formatAlignment(Composite composite) {
|
||||
StringBuffer alignmentBuffer = new StringBuffer();
|
||||
if (!composite.isInternallyAligned()) {
|
||||
alignmentBuffer.append("Unaligned");
|
||||
}
|
||||
else if (composite.isDefaultAligned()) {
|
||||
alignmentBuffer.append("Aligned");
|
||||
}
|
||||
else if (composite.isMachineAligned()) {
|
||||
alignmentBuffer.append("Machine aligned");
|
||||
}
|
||||
else {
|
||||
long alignment = composite.getMinimumAlignment();
|
||||
alignmentBuffer.append("align(" + alignment + ")");
|
||||
}
|
||||
if (composite.isInternallyAligned()) {
|
||||
long packingValue = composite.getPackingValue();
|
||||
if (packingValue != Composite.NOT_PACKING) {
|
||||
alignmentBuffer.append(" pack(" + packingValue + ")");
|
||||
}
|
||||
}
|
||||
|
||||
insertString(alignmentBuffer.toString() + "\n\n", sourceAttrSet);
|
||||
String str = CompositeDataTypeImpl.getAlignmentAndPackingString(composite);
|
||||
insertString(str + "\n\n", sourceAttrSet);
|
||||
}
|
||||
|
||||
private void insertAlignment(Composite composite) {
|
||||
@@ -202,7 +182,7 @@ class DataTypePanel extends JPanel {
|
||||
buffer.append("[0]");
|
||||
}
|
||||
else if (dt instanceof BitFieldDataType &&
|
||||
!((Composite) dtc.getParent()).isInternallyAligned()) {
|
||||
!((Composite) dtc.getParent()).isPackingEnabled()) {
|
||||
BitFieldDataType bfDt = (BitFieldDataType) dt;
|
||||
buffer.append("(");
|
||||
buffer.append(Integer.toString(bfDt.getBitOffset()));
|
||||
@@ -255,24 +235,24 @@ class DataTypePanel extends JPanel {
|
||||
DataTypeComponent[] components = comp.getDefinedComponents();
|
||||
DataTypeComponent flexDtc = null;
|
||||
if (comp instanceof Structure) {
|
||||
showComponentOffset = !comp.isInternallyAligned();
|
||||
showComponentOffset = !comp.isPackingEnabled();
|
||||
flexDtc = ((Structure) comp).getFlexibleArrayComponent();
|
||||
}
|
||||
|
||||
int offsetLength = showComponentOffset ? Integer.toHexString(comp.getLength()).length() : 0;
|
||||
int maxDtNameLength = 10;
|
||||
int maxFieldNameLength = 1;
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
maxDtNameLength = max(getDataTypeName(components[i]), maxDtNameLength);
|
||||
maxFieldNameLength = max(components[i].getFieldName(), maxFieldNameLength);
|
||||
for (DataTypeComponent component : components) {
|
||||
maxDtNameLength = max(getDataTypeName(component), maxDtNameLength);
|
||||
maxFieldNameLength = max(component.getFieldName(), maxFieldNameLength);
|
||||
}
|
||||
if (flexDtc != null) {
|
||||
maxDtNameLength = max(getDataTypeName(flexDtc), maxDtNameLength);
|
||||
maxFieldNameLength = max(flexDtc.getFieldName(), maxFieldNameLength);
|
||||
}
|
||||
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
renderComponent(components[i], maxDtNameLength, maxFieldNameLength, offsetLength);
|
||||
for (DataTypeComponent component : components) {
|
||||
renderComponent(component, maxDtNameLength, maxFieldNameLength, offsetLength);
|
||||
}
|
||||
if (flexDtc != null) {
|
||||
renderComponent(flexDtc, maxDtNameLength, maxFieldNameLength, offsetLength);
|
||||
@@ -293,9 +273,9 @@ class DataTypePanel extends JPanel {
|
||||
|
||||
String[] names = enuum.getNames();
|
||||
int maxLength = 0;
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if (names[i].length() > maxLength) {
|
||||
maxLength = names[i].length();
|
||||
for (String name : names) {
|
||||
if (name.length() > maxLength) {
|
||||
maxLength = name.length();
|
||||
}
|
||||
}
|
||||
long[] values = enuum.getValues();
|
||||
@@ -336,8 +316,8 @@ class DataTypePanel extends JPanel {
|
||||
return;
|
||||
}
|
||||
int maxLength = 0;
|
||||
for (int i = 0; i < vars.length; i++) {
|
||||
String typeName = vars[i].getDataType().getDisplayName();
|
||||
for (ParameterDefinition var : vars) {
|
||||
String typeName = var.getDataType().getDisplayName();
|
||||
if (typeName.length() > maxLength) {
|
||||
maxLength = typeName.length();
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ public class AddBitFieldAction extends CompositeEditorTableAction {
|
||||
public void adjustEnablement() {
|
||||
boolean enabled = true;
|
||||
CompEditorModel editorModel = (CompEditorModel) model;
|
||||
// Union do not support unaligned placement of bitfields
|
||||
if (!(editorModel.viewComposite instanceof Structure) || editorModel.isAligned() ||
|
||||
// Union do not support non-packed placement of bitfields
|
||||
if (!(editorModel.viewComposite instanceof Structure) || editorModel.isPackingEnabled() ||
|
||||
editorModel.getNumSelectedRows() != 1 || editorModel.isFlexibleArraySelection()) {
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
private Composite composite;
|
||||
private CompositeChangeListener listener;
|
||||
|
||||
private BitFieldEditorPanel bitFieldEditorPanel; // for unaligned use case
|
||||
private BitFieldEditorPanel bitFieldEditorPanel; // for non-packed use case
|
||||
|
||||
BitFieldEditorDialog(Composite composite, DataTypeManagerService dtmService, int editOrdinal,
|
||||
boolean showOffsetsInHex, CompositeChangeListener listener) {
|
||||
@@ -290,11 +290,11 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
}
|
||||
|
||||
private static String getCompositeType(Composite composite) {
|
||||
// currently supports unaligned case only!
|
||||
if (composite.isInternallyAligned()) {
|
||||
throw new IllegalArgumentException("Aligned use not supported");
|
||||
// currently supports non-packed case only!
|
||||
if (composite.isPackingEnabled()) {
|
||||
throw new IllegalArgumentException("Packed use not supported");
|
||||
}
|
||||
String alignmentMode = composite.isInternallyAligned() ? "Aligned" : "Unaligned";
|
||||
String alignmentMode = composite.isPackingEnabled() ? "Packed" : "Non-Packed";
|
||||
String type = (composite instanceof Union) ? "Union" : "Structure";
|
||||
return alignmentMode + " " + type;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
baseDataType = ((BitFieldDataType) dtc.getDataType()).getBaseDataType();
|
||||
}
|
||||
}
|
||||
else if (!composite.isNotYetDefined()) {
|
||||
else if (!composite.isZeroLength()) {
|
||||
offset = composite.getLength();
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public class BitFieldEditorDialog extends DialogComponentProvider {
|
||||
|
||||
// Assume a reasonable alignment in identifying aligned offset
|
||||
int alignment = CompositeAlignmentHelper.getPackedAlignment(dataOrganization,
|
||||
Composite.NOT_PACKING, bitfieldDt.getBaseDataType(), bitfieldDt.getBaseTypeSize());
|
||||
CompositeInternal.NO_PACKING, bitfieldDtc);
|
||||
|
||||
int adjustedOffset = offset - (offset % alignment);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import resources.ResourceManager;
|
||||
|
||||
/**
|
||||
* <code>BitFieldEditorPanel</code> provides the ability to add or modify bitfields
|
||||
* within unaligned structures.
|
||||
* within non-packed structures.
|
||||
*/
|
||||
public class BitFieldEditorPanel extends JPanel {
|
||||
|
||||
@@ -81,9 +81,9 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
super();
|
||||
this.composite = composite;
|
||||
|
||||
if (composite.isInternallyAligned()) {
|
||||
if (composite.isPackingEnabled()) {
|
||||
// A different bitfield editor should be used for aligned composites
|
||||
throw new IllegalArgumentException("composite must be unaligned");
|
||||
throw new IllegalArgumentException("composite must be non-packed");
|
||||
}
|
||||
|
||||
setLayout(new VerticalLayout(5));
|
||||
@@ -169,7 +169,7 @@ public class BitFieldEditorPanel extends JPanel {
|
||||
|
||||
int offset = placementComponent.getAllocationOffset();
|
||||
decrementButton.setEnabled(offset > 0);
|
||||
int length = composite.isNotYetDefined() ? 0 : composite.getLength();
|
||||
int length = composite.isZeroLength() ? 0 : composite.getLength();
|
||||
incrementButton.setEnabled(offset < length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
}
|
||||
allocationByteOffset = 0;
|
||||
allocationByteSize = 1;
|
||||
if (!editUseEnabled) {
|
||||
if (!editUseEnabled && composite != null) {
|
||||
allocationByteSize = composite.getLength();
|
||||
}
|
||||
init(null);
|
||||
@@ -456,7 +456,7 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
composite.delete(editOrdinal);
|
||||
|
||||
int sizeChange = initialLength - composite.getLength();
|
||||
if (!composite.isInternallyAligned() && editOrdinal < composite.getNumComponents()) {
|
||||
if (!composite.isPackingEnabled() && editOrdinal < composite.getNumComponents()) {
|
||||
// deletions cause shift which is bad - pad with defaults
|
||||
for (int i = 0; i < sizeChange; i++) {
|
||||
composite.insert(editOrdinal, DataType.DEFAULT);
|
||||
@@ -851,7 +851,7 @@ public class BitFieldPlacementComponent extends JPanel implements Scrollable {
|
||||
BitFieldDataType bitfield = (BitFieldDataType) component.getDataType();
|
||||
int storageSize = 8 * bitfield.getStorageSize();
|
||||
rightBit = leftAdj + storageSize - bitfield.getBitOffset() - 1;
|
||||
// Use effective bit-size since unaligned uses are only concerned with actual
|
||||
// Use effective bit-size since non-packed uses are only concerned with actual
|
||||
// bits stored (NOTE: this may cause a transition from declared to effective
|
||||
// bit-size when editing a bitfield where the these bit-sizes differ).
|
||||
int bitSize = bitfield.getBitSize();
|
||||
|
||||
@@ -21,7 +21,6 @@ import docking.widgets.OptionDialog;
|
||||
import docking.widgets.fieldpanel.support.*;
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Composite.AlignmentType;
|
||||
import ghidra.program.model.lang.InsufficientBytesException;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
@@ -232,7 +231,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
int numComps = getNumComponents();
|
||||
|
||||
// Make sure we don't have a selection with rows outside the table.
|
||||
// This can happen due to switching between aligned and unaligned.
|
||||
// This can happen due to switching between packed and non-packed.
|
||||
FieldSelection allRows = new FieldSelection();
|
||||
allRows.addRange(0, numComps + 1);
|
||||
selection.intersect(allRows);
|
||||
@@ -346,30 +345,31 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
* and does not perform any edit notification.
|
||||
*
|
||||
* @param rows array with each row (component) index to delete
|
||||
* @param monitor the task monitor
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private void delete(int[] rows, TaskMonitor monitor) throws CancelledException {
|
||||
private void delete(int[] rows) throws CancelledException {
|
||||
|
||||
int n = rows.length;
|
||||
monitor.initialize(n);
|
||||
|
||||
int[] selectedRows = getSelectedRows();
|
||||
Arrays.sort(rows);
|
||||
|
||||
Set<Integer> rowSet = new HashSet<>();
|
||||
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
monitor.checkCanceled();
|
||||
monitor.setMessage("Deleting " + (n - i + 1) + " of " + n);
|
||||
int rowIndex = rows[i];
|
||||
int componentOrdinal = convertRowToOrdinal(rowIndex);
|
||||
doDelete(componentOrdinal);
|
||||
monitor.incrementProgress(1);
|
||||
if (componentOrdinal < row) {
|
||||
row--;
|
||||
}
|
||||
rowSet.add(componentOrdinal);
|
||||
}
|
||||
|
||||
viewComposite.delete(rowSet);
|
||||
|
||||
// Not sure if this is the right behavior. Assuming the deleted rows were selected,
|
||||
// restore the selection to be the first row that was deleted so that the UI leaves the
|
||||
// user's selection close to where it was.
|
||||
if (selectedRows.length > 0) {
|
||||
setSelection(new int[] { selectedRows[0] });
|
||||
if (rows.length > 0) {
|
||||
setSelection(new int[] { rows[0] });
|
||||
}
|
||||
|
||||
notifyCompositeChanged();
|
||||
@@ -409,14 +409,13 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
final int entries = endRowIndex - startRowIndex + 1;
|
||||
int[] ordinals = new int[entries];
|
||||
Set<Integer> ordinals = new HashSet<>();
|
||||
|
||||
monitor.initialize(entries);
|
||||
int i = 0;
|
||||
for (int rowIndex = endRowIndex; rowIndex >= startRowIndex; rowIndex--, i++) {
|
||||
for (int rowIndex = endRowIndex; rowIndex >= startRowIndex; rowIndex--) {
|
||||
monitor.checkCanceled();
|
||||
int componentOrdinal = convertRowToOrdinal(rowIndex);
|
||||
ordinals[i] = componentOrdinal;
|
||||
ordinals.add(componentOrdinal);
|
||||
if (componentOrdinal < row) {
|
||||
row--;
|
||||
}
|
||||
@@ -432,7 +431,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSelectedComponents(TaskMonitor monitor) throws UsrException {
|
||||
public void deleteSelectedComponents() throws UsrException {
|
||||
if (!isDeleteAllowed()) {
|
||||
throw new UsrException("Deleting is not allowed.");
|
||||
}
|
||||
@@ -443,7 +442,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
int[] selectedComponents = getSelectedComponentRows();
|
||||
int firstRowIndex = !selection.isEmpty() ? selectedComponents[0] : getRowCount();
|
||||
try {
|
||||
delete(selectedComponents, monitor);
|
||||
delete(selectedComponents);
|
||||
}
|
||||
finally {
|
||||
componentEdited();
|
||||
@@ -1531,7 +1530,7 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
}
|
||||
DataType dt = getComponent(rowIndex).getDataType();
|
||||
int maxDups = Integer.MAX_VALUE;
|
||||
// If editModel is showing undefined bytes (unaligned)
|
||||
// If editModel is showing undefined bytes (non-packed)
|
||||
// then constrain by number of undefined bytes that follow.
|
||||
if (isShowingUndefinedBytes() && (dt != DataType.DEFAULT)) {
|
||||
int numBytes = getNumUndefinedBytesAt(rowIndex + 1);
|
||||
@@ -1609,23 +1608,6 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
return rowIndex;
|
||||
}
|
||||
|
||||
public boolean isAligned() {
|
||||
return viewComposite.isInternallyAligned();
|
||||
}
|
||||
|
||||
public void setAligned(boolean aligned) {
|
||||
boolean currentViewIsAligned = viewComposite.isInternallyAligned();
|
||||
if (currentViewIsAligned == aligned) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setInternallyAligned(aligned);
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
public int getPackingValue() {
|
||||
return viewComposite.getPackingValue();
|
||||
}
|
||||
|
||||
protected boolean isSizeEditable() {
|
||||
return false;
|
||||
}
|
||||
@@ -1644,69 +1626,102 @@ public abstract class CompEditorModel extends CompositeEditorModel {
|
||||
hadChanges = false;
|
||||
return hadChanges;
|
||||
}
|
||||
hadChanges = !(viewComposite.isInternallyAligned() == oldComposite.isInternallyAligned() &&
|
||||
viewComposite.getPackingValue() == oldComposite.getPackingValue() &&
|
||||
viewComposite.isDefaultAligned() == oldComposite.isDefaultAligned() &&
|
||||
viewComposite.isMachineAligned() == oldComposite.isMachineAligned() &&
|
||||
viewComposite.getMinimumAlignment() == oldComposite.getMinimumAlignment());
|
||||
|
||||
PackingType packingType = getPackingType();
|
||||
AlignmentType alignmentType = getAlignmentType();
|
||||
|
||||
hadChanges = (packingType != oldComposite.getPackingType()) ||
|
||||
(alignmentType != oldComposite.getAlignmentType()) ||
|
||||
(packingType == PackingType.EXPLICIT &&
|
||||
getExplicitPackingValue() != oldComposite.getExplicitPackingValue()) ||
|
||||
(alignmentType == AlignmentType.EXPLICIT &&
|
||||
getExplicitMinimumAlignment() != oldComposite.getExplicitMinimumAlignment());
|
||||
return hadChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the external (minimum) alignment type for the structure or union being viewed
|
||||
* Return the (minimum) alignment type for the structure or union being viewed
|
||||
* @return the alignment type
|
||||
*/
|
||||
public AlignmentType getMinimumAlignmentType() {
|
||||
if (viewComposite.isDefaultAligned()) {
|
||||
return AlignmentType.DEFAULT_ALIGNED;
|
||||
}
|
||||
if (viewComposite.isMachineAligned()) {
|
||||
return AlignmentType.MACHINE_ALIGNED;
|
||||
}
|
||||
return AlignmentType.ALIGNED_BY_VALUE;
|
||||
public AlignmentType getAlignmentType() {
|
||||
return viewComposite.getAlignmentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the external (minimum) alignment value for the structure or union being viewed.
|
||||
* @return the alignment
|
||||
*/
|
||||
public int getMinimumAlignment() {
|
||||
if (viewComposite != null) {
|
||||
return viewComposite.getMinimumAlignment();
|
||||
}
|
||||
return 0;
|
||||
public int getExplicitMinimumAlignment() {
|
||||
return viewComposite.getExplicitMinimumAlignment();
|
||||
}
|
||||
|
||||
public void setAlignmentType(AlignmentType alignmentType) {
|
||||
if (alignmentType == AlignmentType.DEFAULT_ALIGNED) {
|
||||
viewComposite.setToDefaultAlignment();
|
||||
public void setAlignmentType(AlignmentType alignmentType, int explicitValue) {
|
||||
AlignmentType currentAlignType = getAlignmentType();
|
||||
if (alignmentType == AlignmentType.DEFAULT) {
|
||||
if (currentAlignType == AlignmentType.DEFAULT) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setToDefaultAligned();
|
||||
}
|
||||
else if (alignmentType == AlignmentType.MACHINE_ALIGNED) {
|
||||
viewComposite.setToMachineAlignment();
|
||||
else if (alignmentType == AlignmentType.MACHINE) {
|
||||
if (currentAlignType == AlignmentType.MACHINE) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setToMachineAligned();
|
||||
}
|
||||
else {
|
||||
int alignment = viewComposite.getMinimumAlignment();
|
||||
if (alignment == 0) {
|
||||
alignment = viewDTM.getDataOrganization().getAlignment(viewComposite, getLength());
|
||||
if (currentAlignType == AlignmentType.EXPLICIT &&
|
||||
explicitValue == viewComposite.getExplicitMinimumAlignment()) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setMinimumAlignment(alignment); // Causes the type to change, but not the value.
|
||||
viewComposite.setExplicitMinimumAlignment(explicitValue);
|
||||
}
|
||||
if (fixSelection()) {
|
||||
selectionChanged();
|
||||
}
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
public abstract void setAlignment(int alignmentValue) throws InvalidInputException;
|
||||
public boolean isPackingEnabled() {
|
||||
return viewComposite.isPackingEnabled();
|
||||
}
|
||||
|
||||
public void setPackingValue(int packingValue) {
|
||||
int currentViewPackingValue = viewComposite.getPackingValue();
|
||||
if (currentViewPackingValue == packingValue) {
|
||||
return;
|
||||
public PackingType getPackingType() {
|
||||
return viewComposite.getPackingType();
|
||||
}
|
||||
|
||||
public int getExplicitPackingValue() {
|
||||
return viewComposite.getExplicitPackingValue();
|
||||
}
|
||||
|
||||
public void setPackingType(PackingType packingType, int explicitValue) {
|
||||
PackingType currentPacktype = getPackingType();
|
||||
if (packingType == PackingType.DISABLED) {
|
||||
if (currentPacktype == PackingType.DISABLED) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setPackingEnabled(false);
|
||||
}
|
||||
else if (packingType == PackingType.DEFAULT) {
|
||||
if (currentPacktype == PackingType.DEFAULT) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setToDefaultPacking();
|
||||
}
|
||||
else {
|
||||
if (currentPacktype == PackingType.EXPLICIT &&
|
||||
explicitValue == viewComposite.getExplicitPackingValue()) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setExplicitPackingValue(explicitValue);
|
||||
}
|
||||
if (fixSelection()) {
|
||||
selectionChanged();
|
||||
}
|
||||
viewComposite.setPackingValue(packingValue);
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
public int getActualAlignment() {
|
||||
return viewDTM.getDataOrganization().getAlignment(viewComposite, getLength());
|
||||
return viewComposite.getAlignment();
|
||||
// return viewDTM.getDataOrganization().getAlignment(viewComposite, getLength());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Enum;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Model for editing a composite data type. Specific composite data type editors
|
||||
@@ -546,7 +545,7 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSelectedComponents(TaskMonitor monitor) throws UsrException {
|
||||
public void deleteSelectedComponents() throws UsrException {
|
||||
if (!isDeleteAllowed()) {
|
||||
throw new UsrException("Deleting is not allowed.");
|
||||
}
|
||||
@@ -610,8 +609,8 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
||||
|
||||
private boolean hasCompPathNameChanges(Composite currentViewComposite, Composite oldComposite) {
|
||||
// Check component data type pathnames.
|
||||
DataTypeComponent[] comps = currentViewComposite.getComponents();
|
||||
DataTypeComponent[] oldComps = oldComposite.getComponents();
|
||||
DataTypeComponent[] comps = currentViewComposite.getDefinedComponents();
|
||||
DataTypeComponent[] oldComps = oldComposite.getDefinedComponents();
|
||||
if (comps.length != oldComps.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract class CompositeEditorPanel extends JPanel
|
||||
|
||||
private boolean launchBitFieldEditor(int modelColumn, int editingRow) {
|
||||
if (model.viewComposite instanceof Structure &&
|
||||
!model.viewComposite.isInternallyAligned() &&
|
||||
!model.viewComposite.isPackingEnabled() &&
|
||||
model.getDataTypeColumn() == modelColumn && editingRow < model.getNumComponents()) {
|
||||
// check if we are attempting to edit a bitfield
|
||||
DataTypeComponent dtComponent = model.getComponent(editingRow);
|
||||
|
||||
@@ -363,7 +363,7 @@ class CompositeViewerModel extends AbstractTableModel implements DataTypeManager
|
||||
* @return this size
|
||||
*/
|
||||
public int getLength() {
|
||||
if (viewComposite != null && !viewComposite.isNotYetDefined()) {
|
||||
if (viewComposite != null && !viewComposite.isZeroLength()) {
|
||||
return viewComposite.getLength();
|
||||
}
|
||||
return 0;
|
||||
@@ -1386,8 +1386,7 @@ class CompositeViewerModel extends AbstractTableModel implements DataTypeManager
|
||||
protected void selectionChanged() {
|
||||
|
||||
updatingSelection(() -> {
|
||||
for (int i = 0; i < modelListeners.size(); i++) {
|
||||
CompositeViewerModelListener listener = modelListeners.get(i);
|
||||
for (CompositeViewerModelListener listener : modelListeners) {
|
||||
listener.selectionChanged();
|
||||
}
|
||||
});
|
||||
@@ -1411,8 +1410,7 @@ class CompositeViewerModel extends AbstractTableModel implements DataTypeManager
|
||||
*/
|
||||
protected <T> void notify(List<T> listeners, Consumer<T> method) {
|
||||
swing(() -> {
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
T listener = listeners.get(i);
|
||||
for (T listener : listeners) {
|
||||
method.accept(listener);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@ public class DeleteAction extends CompositeEditorTableAction {
|
||||
|
||||
private void doDelete(TaskMonitor monitor) {
|
||||
try {
|
||||
model.deleteSelectedComponents(monitor);
|
||||
model.deleteSelectedComponents();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// user cancelled
|
||||
|
||||
@@ -48,7 +48,7 @@ public class EditBitFieldAction extends CompositeEditorTableAction {
|
||||
private DataTypeComponent getUnalignedBitFieldComponent() {
|
||||
CompEditorModel editorModel = (CompEditorModel) model;
|
||||
if ((editorModel.viewComposite instanceof Structure) &&
|
||||
!editorModel.viewComposite.isInternallyAligned() &&
|
||||
!editorModel.viewComposite.isPackingEnabled() &&
|
||||
editorModel.getNumSelectedRows() == 1) {
|
||||
int rowIndex = model.getSelectedRows()[0];
|
||||
if (rowIndex < model.getNumComponents()) {
|
||||
|
||||
@@ -322,8 +322,7 @@ public interface EditorModel {
|
||||
public void cycleDataType(CycleGroup cycleGroup);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param parent
|
||||
* Create array component
|
||||
* @throws UsrException
|
||||
*/
|
||||
public void createArray() throws UsrException;
|
||||
@@ -331,10 +330,9 @@ public interface EditorModel {
|
||||
/**
|
||||
* Delete the selected components.
|
||||
*
|
||||
* @param monitor the task monitor
|
||||
* @throws UsrException if the data type isn't allowed to be deleted.
|
||||
*/
|
||||
public void deleteSelectedComponents(TaskMonitor monitor) throws UsrException;
|
||||
public void deleteSelectedComponents() throws UsrException;
|
||||
|
||||
/**
|
||||
* Creates multiple duplicates of the indicated component.
|
||||
|
||||
@@ -58,7 +58,7 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
||||
int index = model.getMinIndexSelected();
|
||||
if (index >= 0) {
|
||||
DataType undefinedDt =
|
||||
model.viewComposite.isInternallyAligned() ? Undefined1DataType.dataType
|
||||
model.viewComposite.isPackingEnabled() ? Undefined1DataType.dataType
|
||||
: DataType.DEFAULT;
|
||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(undefinedDt, -1);
|
||||
model.insert(index, dti.getDataType(), dti.getLength());
|
||||
@@ -77,7 +77,7 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
||||
if (model.viewComposite instanceof Structure) {
|
||||
boolean isContiguousSelection = model.getSelection().getNumRanges() == 1;
|
||||
DataType undefinedDt =
|
||||
model.viewComposite.isInternallyAligned() ? Undefined1DataType.dataType
|
||||
model.viewComposite.isPackingEnabled() ? Undefined1DataType.dataType
|
||||
: DataType.DEFAULT;
|
||||
enabled = isContiguousSelection &&
|
||||
model.isInsertAllowed(model.getMinIndexSelected(), undefinedDt);
|
||||
|
||||
@@ -25,7 +25,6 @@ import docking.widgets.dialogs.InputDialogListener;
|
||||
import docking.widgets.fieldpanel.support.FieldRange;
|
||||
import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
import ghidra.docking.settings.SettingsImpl;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.InsufficientBytesException;
|
||||
import ghidra.util.Msg;
|
||||
@@ -201,17 +200,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
|
||||
@Override
|
||||
public int getNumComponents() {
|
||||
if (viewComposite == null) {
|
||||
return 0;
|
||||
}
|
||||
if (isShowingUndefinedBytes()) {
|
||||
if (viewComposite.isNotYetDefined()) {
|
||||
return 0;
|
||||
}
|
||||
return viewComposite.getNumComponents();
|
||||
}
|
||||
DataTypeComponent[] definedComponents = ((Structure) viewComposite).getDefinedComponents();
|
||||
return definedComponents.length;
|
||||
return viewComposite == null ? 0 : viewComposite.getNumComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,14 +241,14 @@ class StructureEditorModel extends CompEditorModel {
|
||||
|
||||
@Override
|
||||
protected boolean isSizeEditable() {
|
||||
return !isAligned();
|
||||
return !isPackingEnabled();
|
||||
}
|
||||
|
||||
void setStructureSize(int size) {
|
||||
if (viewComposite == null) {
|
||||
return;
|
||||
}
|
||||
int currentLength = viewComposite.isNotYetDefined() ? 0 : viewComposite.getLength();
|
||||
int currentLength = viewComposite.isZeroLength() ? 0 : viewComposite.getLength();
|
||||
if (currentLength == size) {
|
||||
return;
|
||||
}
|
||||
@@ -449,8 +438,8 @@ class StructureEditorModel extends CompEditorModel {
|
||||
DataTypeComponent comp = deleteComponentAndResidual(startIndex - 1);
|
||||
|
||||
try {
|
||||
if (!isAligned() && comp.isBitFieldComponent()) {
|
||||
// insert residual undefined bytes before inserting unaligned bitfield
|
||||
if (!isPackingEnabled() && comp.isBitFieldComponent()) {
|
||||
// insert residual undefined bytes before inserting non-packed bitfield
|
||||
int lenChange = len - getLength();
|
||||
insert(endIndex, DataType.DEFAULT, 1, lenChange, TaskMonitor.DUMMY);
|
||||
}
|
||||
@@ -485,8 +474,8 @@ class StructureEditorModel extends CompEditorModel {
|
||||
DataTypeComponent comp = deleteComponentAndResidual(endIndex + 1);
|
||||
|
||||
try {
|
||||
if (!isAligned() && comp.isBitFieldComponent()) {
|
||||
// insert residual undefined bytes before inserting unaligned bitfield
|
||||
if (!isPackingEnabled() && comp.isBitFieldComponent()) {
|
||||
// insert residual undefined bytes before inserting non-packed bitfield
|
||||
int lenChange = len - getLength();
|
||||
insert(startIndex, DataType.DEFAULT, 1, lenChange, TaskMonitor.DUMMY);
|
||||
}
|
||||
@@ -507,7 +496,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
DataTypeComponent comp = getComponent(index);
|
||||
deleteComponent(index);
|
||||
|
||||
if (isAligned() || !comp.isBitFieldComponent() || index >= getNumComponents()) {
|
||||
if (isPackingEnabled() || !comp.isBitFieldComponent() || index >= getNumComponents()) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
@@ -627,7 +616,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSelectedComponents(TaskMonitor monitor) throws UsrException {
|
||||
public void deleteSelectedComponents() throws UsrException {
|
||||
if (!isDeleteAllowed()) {
|
||||
throw new UsrException("Deleting is not allowed.");
|
||||
}
|
||||
@@ -646,7 +635,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
selectionChanged();
|
||||
return;
|
||||
}
|
||||
super.deleteSelectedComponents(monitor);
|
||||
super.deleteSelectedComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -660,14 +649,14 @@ class StructureEditorModel extends CompEditorModel {
|
||||
int rowIndex = getRow();
|
||||
DataTypeComponent comp = getComponent(rowIndex);
|
||||
DataType dt = comp.getDataType();
|
||||
if (viewComposite.isInternallyAligned()) {
|
||||
if (viewComposite.isPackingEnabled()) {
|
||||
return true;
|
||||
}
|
||||
if (dt.equals(DataType.DEFAULT)) {
|
||||
return true; // Insert an undefined and push everything down.
|
||||
}
|
||||
if (comp.isBitFieldComponent()) {
|
||||
return false; // unable to place unaligned bitfield in a reasonable fashion
|
||||
return false; // unable to place non-packed bitfield in a reasonable fashion
|
||||
}
|
||||
// Can always duplicate at the end.
|
||||
if (isAtEnd(rowIndex) || onlyUndefinedsUntilEnd(rowIndex + 1)) {
|
||||
@@ -956,7 +945,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
dtc.getComment());
|
||||
}
|
||||
else {
|
||||
if (isAligned() || !(dataType instanceof BitFieldDataType)) {
|
||||
if (isPackingEnabled() || !(dataType instanceof BitFieldDataType)) {
|
||||
dtc = ((Structure) viewComposite).insert(rowIndex, dataType, length, name,
|
||||
comment);
|
||||
}
|
||||
@@ -1174,41 +1163,9 @@ class StructureEditorModel extends CompEditorModel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAligned(boolean aligned) {
|
||||
boolean currentViewIsAligned = viewComposite.isInternallyAligned();
|
||||
if (currentViewIsAligned == aligned) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setInternallyAligned(aligned);
|
||||
if (fixSelection()) {
|
||||
selectionChanged();
|
||||
}
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
public void adjustAlignment(PluginTool tool, int minAlignment) {
|
||||
int currentViewAlignment = viewComposite.getMinimumAlignment();
|
||||
if (currentViewAlignment == minAlignment) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setMinimumAlignment(minAlignment);
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlignment(int minAlignment) throws InvalidInputException {
|
||||
int currentViewAlignment = viewComposite.getMinimumAlignment();
|
||||
if (currentViewAlignment == minAlignment) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setMinimumAlignment(minAlignment);
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowingUndefinedBytes() {
|
||||
return !viewComposite.isInternallyAligned();
|
||||
return !viewComposite.isPackingEnabled();
|
||||
}
|
||||
|
||||
public void createInternalStructure(TaskMonitor monitor)
|
||||
@@ -1259,7 +1216,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
final StructureDataType structureDataType =
|
||||
new StructureDataType(originalCategoryPath, uniqueName, length, originalDTM);
|
||||
|
||||
// if (isAligned()) {
|
||||
// if (isPackingEnabled()) {
|
||||
// structureDataType.setPackingValue(getPackingValue());
|
||||
// }
|
||||
|
||||
@@ -1281,7 +1238,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
|
||||
length += compLength;
|
||||
|
||||
if (!structureDataType.isInternallyAligned() && component.isBitFieldComponent()) {
|
||||
if (!structureDataType.isPackingEnabled() && component.isBitFieldComponent()) {
|
||||
BitFieldDataType bitfield = (BitFieldDataType) dt;
|
||||
structureDataType.insertBitFieldAt(component.getOffset() - firstDtc.getOffset(),
|
||||
compLength, bitfield.getBitOffset(), bitfield.getBaseDataType(),
|
||||
@@ -1296,8 +1253,8 @@ class StructureEditorModel extends CompEditorModel {
|
||||
lastDtc = component;
|
||||
}
|
||||
DataType addedDataType = createDataTypeInOriginalDTM(structureDataType);
|
||||
if (viewComposite.isInternallyAligned()) {
|
||||
deleteSelectedComponents(monitor);
|
||||
if (viewComposite.isPackingEnabled()) {
|
||||
deleteSelectedComponents();
|
||||
insert(minRow, addedDataType, addedDataType.getLength());
|
||||
}
|
||||
else {
|
||||
@@ -1434,7 +1391,7 @@ class StructureEditorModel extends CompEditorModel {
|
||||
DataTypeComponent dtc = struct.getComponent(i);
|
||||
DataType dt = dtc.getDataType();
|
||||
int compLength = dtc.getLength();
|
||||
if (!isAligned()) {
|
||||
if (!isPackingEnabled()) {
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
BitFieldDataType bitfield = (BitFieldDataType) dt;
|
||||
viewStruct.insertBitFieldAt(currentOffset + dtc.getOffset(), compLength,
|
||||
|
||||
@@ -40,7 +40,8 @@ import docking.widgets.fieldpanel.support.FieldSelection;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.InsufficientBytesException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.UsrException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
class UnionEditorModel extends CompEditorModel {
|
||||
@@ -502,16 +503,6 @@ class UnionEditorModel extends CompEditorModel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlignment(int minAlignment) throws InvalidInputException {
|
||||
long currentViewAlignment = viewComposite.getMinimumAlignment();
|
||||
if (currentViewAlignment == minAlignment) {
|
||||
return;
|
||||
}
|
||||
viewComposite.setMinimumAlignment(minAlignment);
|
||||
notifyCompositeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of undefined bytes that are available in the structure
|
||||
* beginning at the specified row index.
|
||||
|
||||
@@ -494,7 +494,6 @@ public class DataTypeSynchronizer {
|
||||
|
||||
dataType.setLastChangeTimeInSourceArchive(0); // Set timestamp so user must re-sync.
|
||||
fixedSync = true;
|
||||
dataTypeManager.dataTypeChanged(dataType);
|
||||
}
|
||||
}
|
||||
if (fixedSync) {
|
||||
|
||||
@@ -152,10 +152,11 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||
addLocalAction(new DeleteArchiveAction(plugin));
|
||||
addLocalAction(new RenameAction(plugin));
|
||||
addLocalAction(new EditAction(plugin));
|
||||
addLocalAction(new AlignDataTypeAction(plugin));
|
||||
// NOTE: it make very little sense to blindly enable packing
|
||||
// addLocalAction(new PackDataTypeAction(plugin));
|
||||
// addLocalAction( new PackDataTypeAction( plugin ));
|
||||
// addLocalAction( new PackSizeDataTypeAction( plugin ));
|
||||
addLocalAction(new AlignAllDataTypesAction(plugin));
|
||||
// addLocalAction(new PackAllDataTypesAction(plugin));
|
||||
// addLocalAction( new DefineDataTypeAlignmentAction( plugin ));
|
||||
addLocalAction(new CreateEnumFromSelectionAction(plugin));
|
||||
|
||||
|
||||
@@ -25,97 +25,62 @@ import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeTreeNode;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class AlignDataTypeAction extends DockingAction {
|
||||
public class Pack1DataTypeAction extends DockingAction {
|
||||
|
||||
private DataTypeManagerPlugin plugin;
|
||||
|
||||
public AlignDataTypeAction(DataTypeManagerPlugin plugin) {
|
||||
super("Align Data Type", plugin.getName());
|
||||
setPopupMenuData(new MenuData(new String[] { "Align" }, "Edit"));
|
||||
setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
DataTypeNode node = getSelectedDataTypeNode(context);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
DataType dataType = node.getDataType();
|
||||
if (dataType instanceof BuiltInDataType || dataType instanceof Pointer ||
|
||||
dataType instanceof MissingBuiltInDataType) {
|
||||
return false;
|
||||
}
|
||||
if (!node.isModifiable()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
public Pack1DataTypeAction(DataTypeManagerPlugin plugin) {
|
||||
super("Pack1 Data Type", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
setPopupMenuData(new MenuData(new String[] { "Pack (1)" }, "Edit"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
DataTypeNode node = getSelectedDataTypeNode(context);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
DataType dataType = node.getDataType();
|
||||
if (dataType instanceof Composite) {
|
||||
return !((Composite) dataType).isInternallyAligned();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private DataTypeNode getSelectedDataTypeNode(ActionContext context) {
|
||||
Object contextObject = context.getContextObject();
|
||||
if (!(contextObject instanceof GTree)) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
GTree gTree = (GTree) contextObject;
|
||||
TreePath[] selectionPaths = gTree.getSelectionPaths();
|
||||
if (selectionPaths.length != 1) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
DataTypeTreeNode node = (DataTypeTreeNode) selectionPaths[0].getLastPathComponent();
|
||||
|
||||
if (!(node instanceof DataTypeNode)) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
return (DataTypeNode) node;
|
||||
setEnabled(node.isModifiable());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = (GTree) context.getContextObject();
|
||||
TreePath[] selectionPaths = gTree.getSelectionPaths();
|
||||
for (TreePath treePath : selectionPaths) {
|
||||
final DataTypeNode dataTypeNode = (DataTypeNode) treePath.getLastPathComponent();
|
||||
DataType dataType = dataTypeNode.getDataType();
|
||||
DataTypeManager dataTypeManager = dataType.getDataTypeManager();
|
||||
DataOrganization dataOrganization = dataTypeManager.getDataOrganization();
|
||||
alignDataType(dataType, dataOrganization);
|
||||
if (selectionPaths.length != 1) {
|
||||
Msg.error(this, "Pack is only allowed on an individual data type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void alignDataType(DataType dataType, DataOrganization dataOrganization) {
|
||||
TreePath treePath = selectionPaths[0];
|
||||
final DataTypeNode dataTypeNode = (DataTypeNode) treePath.getLastPathComponent();
|
||||
DataType dataType = dataTypeNode.getDataType();
|
||||
DataTypeManager dataTypeManager = dataType.getDataTypeManager();
|
||||
if (dataTypeManager == null) {
|
||||
Msg.error(this, "Can't align data type " + dataType.getName() +
|
||||
" without a data type manager.");
|
||||
return;
|
||||
}
|
||||
if (!(dataType instanceof Structure)) {
|
||||
Msg.error(this, "Can't align data type " + dataType.getName() +
|
||||
". It's not a structure.");
|
||||
Msg.error(this,
|
||||
"Can't pack data type " + dataType.getName() + " without a data type manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
int transactionID = -1;
|
||||
boolean commit = false;
|
||||
try {
|
||||
// start a transaction
|
||||
transactionID = dataTypeManager.startTransaction("align " + dataType.getName());
|
||||
((Structure) dataType).setInternallyAligned(true);
|
||||
transactionID = dataTypeManager.startTransaction("pack of " + dataType.getName());
|
||||
packDataType(dataType);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -124,4 +89,13 @@ public class AlignDataTypeAction extends DockingAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void packDataType(DataType dataType) {
|
||||
if (!(dataType instanceof Composite)) {
|
||||
Msg.error(this,
|
||||
"Can't pack data type " + dataType.getName() + ". It's not a composite.");
|
||||
return;
|
||||
}
|
||||
((Composite) dataType).pack(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,19 +29,18 @@ import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.archive.Archive;
|
||||
import ghidra.app.plugin.core.datamgr.tree.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class AlignAllDataTypesAction extends DockingAction {
|
||||
public class PackAllDataTypesAction extends DockingAction {
|
||||
|
||||
private DataTypeManagerPlugin plugin;
|
||||
|
||||
public AlignAllDataTypesAction(DataTypeManagerPlugin plugin) {
|
||||
super("Align All Data Types", plugin.getName());
|
||||
public PackAllDataTypesAction(DataTypeManagerPlugin plugin) {
|
||||
super("Pack All Composites", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
|
||||
setPopupMenuData(new MenuData(new String[] { "Align All..." }, "Edit"));
|
||||
setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
||||
setPopupMenuData(new MenuData(new String[] { "Pack All..." }, "Edit"));
|
||||
// setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,27 +84,27 @@ public class AlignAllDataTypesAction extends DockingAction {
|
||||
int result =
|
||||
OptionDialog.showOptionDialog(
|
||||
plugin.getTool().getToolFrame(),
|
||||
"Align Data Types",
|
||||
"Are you sure you want to align all of the data types in " +
|
||||
"Pack All Composites",
|
||||
"Are you sure you want to enable packing of all non-packed composites in " +
|
||||
dataTypeManager.getName() +
|
||||
"?\nBoth structures and unions that are currently unaligned will become aligned.\n" +
|
||||
"This could cause component offsets to change and datatype sizes to change.\n" +
|
||||
"?\nAll structures and unions that are not currently packed will default packing enabled.\n" +
|
||||
"This could cause component offsets to change as well as size and alignment of these data types to change.\n" +
|
||||
"Do you want to continue?", "Continue", OptionDialog.WARNING_MESSAGE);
|
||||
if (result == OptionDialog.CANCEL_OPTION) {
|
||||
return;
|
||||
}
|
||||
alignDataTypes(dataTypeManager, dataOrganization);
|
||||
packDataTypes(dataTypeManager, dataOrganization);
|
||||
}
|
||||
else {
|
||||
Msg.showWarn(this, gTree, "Alignment Not Allowed",
|
||||
"The archive must be modifiable to align data types.");
|
||||
Msg.showWarn(this, gTree, "Modification Not Allowed",
|
||||
"The archive must be modifiable to pack data types.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void alignDataTypes(DataTypeManager dataTypeManager, DataOrganization dataOrganization) {
|
||||
private void packDataTypes(DataTypeManager dataTypeManager, DataOrganization dataOrganization) {
|
||||
if (dataTypeManager == null) {
|
||||
Msg.error(this, "Can't align data types without a data type manager.");
|
||||
Msg.error(this, "Can't pack data types without a data type manager.");
|
||||
return;
|
||||
}
|
||||
int transactionID = -1;
|
||||
@@ -113,9 +112,8 @@ public class AlignAllDataTypesAction extends DockingAction {
|
||||
try {
|
||||
// start a transaction
|
||||
transactionID =
|
||||
dataTypeManager.startTransaction("Align all data types in " +
|
||||
dataTypeManager.getName());
|
||||
alignEachStructure(dataTypeManager, dataOrganization);
|
||||
dataTypeManager.startTransaction("Pack Composite Types");
|
||||
packEachStructure(dataTypeManager, dataOrganization);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -124,12 +122,14 @@ public class AlignAllDataTypesAction extends DockingAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void alignEachStructure(DataTypeManager dataTypeManager,
|
||||
private void packEachStructure(DataTypeManager dataTypeManager,
|
||||
DataOrganization dataOrganization) {
|
||||
Iterator<? extends Composite> allComposites = dataTypeManager.getAllComposites();
|
||||
while (allComposites.hasNext()) {
|
||||
Composite composite = allComposites.next();
|
||||
composite.setInternallyAligned(true);
|
||||
if (!composite.isPackingEnabled()) {
|
||||
composite.setPackingEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,81 +26,101 @@ import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeTreeNode;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class PackDataTypeAction extends DockingAction {
|
||||
|
||||
private DataTypeManagerPlugin plugin;
|
||||
|
||||
public PackDataTypeAction(DataTypeManagerPlugin plugin) {
|
||||
super("Pack Data Type", plugin.getName());
|
||||
this.plugin = plugin;
|
||||
setPopupMenuData(new MenuData(new String[] { "Pack" }, "Edit"));
|
||||
setPopupMenuData(new MenuData(new String[] { "Pack (default)" }, "Edit"));
|
||||
// setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
DataTypeNode node = getSelectedDataTypeNode(context);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
DataType dataType = node.getDataType();
|
||||
if (dataType instanceof BuiltInDataType || dataType instanceof Pointer ||
|
||||
dataType instanceof MissingBuiltInDataType) {
|
||||
return false;
|
||||
}
|
||||
if (!node.isModifiable()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
DataTypeNode node = getSelectedDataTypeNode(context);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
DataType dataType = node.getDataType();
|
||||
if (dataType instanceof Composite) {
|
||||
return !((Composite) dataType).isPackingEnabled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private DataTypeNode getSelectedDataTypeNode(ActionContext context) {
|
||||
Object contextObject = context.getContextObject();
|
||||
if (!(contextObject instanceof GTree)) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
GTree gTree = (GTree) contextObject;
|
||||
TreePath[] selectionPaths = gTree.getSelectionPaths();
|
||||
if (selectionPaths.length != 1) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
DataTypeTreeNode node = (DataTypeTreeNode) selectionPaths[0].getLastPathComponent();
|
||||
|
||||
if (!(node instanceof DataTypeNode)) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
setEnabled(node.isModifiable());
|
||||
return true;
|
||||
return (DataTypeNode) node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = (GTree) context.getContextObject();
|
||||
TreePath[] selectionPaths = gTree.getSelectionPaths();
|
||||
if (selectionPaths.length != 1) {
|
||||
Msg.error(this, "Pack is only allowed on an individual data type.");
|
||||
return;
|
||||
for (TreePath treePath : selectionPaths) {
|
||||
final DataTypeNode dataTypeNode = (DataTypeNode) treePath.getLastPathComponent();
|
||||
DataType dataType = dataTypeNode.getDataType();
|
||||
DataTypeManager dataTypeManager = dataType.getDataTypeManager();
|
||||
DataOrganization dataOrganization = dataTypeManager.getDataOrganization();
|
||||
alignDataType(dataType, dataOrganization);
|
||||
}
|
||||
TreePath treePath = selectionPaths[0];
|
||||
final DataTypeNode dataTypeNode = (DataTypeNode) treePath.getLastPathComponent();
|
||||
DataType dataType = dataTypeNode.getDataType();
|
||||
}
|
||||
|
||||
private void alignDataType(DataType dataType, DataOrganization dataOrganization) {
|
||||
DataTypeManager dataTypeManager = dataType.getDataTypeManager();
|
||||
if (dataTypeManager == null) {
|
||||
Msg.error(this,
|
||||
"Can't pack data type " + dataType.getName() + " without a data type manager.");
|
||||
Msg.error(this, "Can't align data type " + dataType.getName() +
|
||||
" without a data type manager.");
|
||||
return;
|
||||
}
|
||||
if (!(dataType instanceof Structure)) {
|
||||
Msg.error(this, "Can't align data type " + dataType.getName() +
|
||||
". It's not a structure.");
|
||||
return;
|
||||
}
|
||||
|
||||
int transactionID = -1;
|
||||
boolean commit = false;
|
||||
try {
|
||||
// start a transaction
|
||||
transactionID = dataTypeManager.startTransaction("pack of " + dataType.getName());
|
||||
packDataType(dataType);
|
||||
transactionID = dataTypeManager.startTransaction("align " + dataType.getName());
|
||||
((Structure) dataType).setPackingEnabled(true);
|
||||
commit = true;
|
||||
}
|
||||
catch (InvalidInputException iie) {
|
||||
// TODO Auto-generated catch block
|
||||
iie.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
// commit the changes
|
||||
dataTypeManager.endTransaction(transactionID, commit);
|
||||
}
|
||||
}
|
||||
|
||||
private void packDataType(DataType dataType) throws InvalidInputException {
|
||||
if (!(dataType instanceof Structure)) {
|
||||
Msg.error(this,
|
||||
"Can't pack data type " + dataType.getName() + ". It's not a structure.");
|
||||
return;
|
||||
}
|
||||
((Structure) dataType).pack(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import ghidra.app.plugin.core.datamgr.tree.DataTypeNode;
|
||||
import ghidra.app.plugin.core.datamgr.tree.DataTypeTreeNode;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class PackSizeDataTypeAction extends DockingAction {
|
||||
|
||||
@@ -73,7 +72,8 @@ public class PackSizeDataTypeAction extends DockingAction {
|
||||
return;
|
||||
}
|
||||
|
||||
NumberInputDialog numberInputDialog = new NumberInputDialog("pack alignment", 0, 0, 16);
|
||||
NumberInputDialog numberInputDialog =
|
||||
new NumberInputDialog("explicit pack value", 0, 0, 16);
|
||||
if (!numberInputDialog.show()) {
|
||||
return;
|
||||
}
|
||||
@@ -88,9 +88,8 @@ public class PackSizeDataTypeAction extends DockingAction {
|
||||
packDataType(dataType, packSize);
|
||||
commit = true;
|
||||
}
|
||||
catch (InvalidInputException iie) {
|
||||
// TODO Auto-generated catch block
|
||||
iie.printStackTrace();
|
||||
catch (IllegalArgumentException iie) {
|
||||
Msg.showError(this, null, "Invalid Pack Value", iie.getMessage());
|
||||
}
|
||||
finally {
|
||||
// commit the changes
|
||||
@@ -98,13 +97,13 @@ public class PackSizeDataTypeAction extends DockingAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void packDataType(DataType dataType, int packSize) throws InvalidInputException {
|
||||
if (!(dataType instanceof Structure)) {
|
||||
private void packDataType(DataType dataType, int packSize) throws IllegalArgumentException {
|
||||
if (!(dataType instanceof Composite)) {
|
||||
Msg.error(this,
|
||||
"Can't pack data type " + dataType.getName() + ". It's not a structure.");
|
||||
"Can't pack data type " + dataType.getName() + ". It's not a composite.");
|
||||
return;
|
||||
}
|
||||
((Structure) dataType).pack(packSize);
|
||||
((Composite) dataType).pack(packSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -463,25 +463,25 @@ public class DataTypeEditorManager
|
||||
return editorOptionMgr.showUnionNumbersInHex();
|
||||
}
|
||||
|
||||
public void createNewStructure(Category category, boolean isInternallyAligned) {
|
||||
public void createNewStructure(Category category, boolean isPacked) {
|
||||
String newName = getUniqueName(category, "struct");
|
||||
DataTypeManager dataTypeManager = category.getDataTypeManager();
|
||||
SourceArchive sourceArchive = dataTypeManager.getLocalSourceArchive();
|
||||
StructureDataType structureDataType =
|
||||
new StructureDataType(category.getCategoryPath(), newName, 0, dataTypeManager);
|
||||
structureDataType.setSourceArchive(sourceArchive);
|
||||
structureDataType.setInternallyAligned(isInternallyAligned);
|
||||
structureDataType.setPackingEnabled(isPacked);
|
||||
edit(structureDataType);
|
||||
}
|
||||
|
||||
public void createNewUnion(Category category, boolean isInternallyAligned) {
|
||||
public void createNewUnion(Category category, boolean isPacked) {
|
||||
String newName = getUniqueName(category, "union");
|
||||
DataTypeManager dataTypeManager = category.getDataTypeManager();
|
||||
SourceArchive sourceArchive = dataTypeManager.getLocalSourceArchive();
|
||||
UnionDataType unionDataType =
|
||||
new UnionDataType(category.getCategoryPath(), newName, dataTypeManager);
|
||||
unionDataType.setSourceArchive(sourceArchive);
|
||||
unionDataType.setInternallyAligned(isInternallyAligned);
|
||||
unionDataType.setPackingEnabled(isPacked);
|
||||
edit(unionDataType);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ public class DataTypePreviewPlugin extends ProgramPlugin {
|
||||
model = new DTPPTableModel();
|
||||
table = new DTPPTable(model);
|
||||
component = new DTPPScrollPane(table);
|
||||
dataTypeManager = new LayeredDataTypeManager();
|
||||
dataTypeManager = new LayeredDataTypeManager(activeProgram);
|
||||
|
||||
addDataType(new ByteDataType());
|
||||
addDataType(new WordDataType());
|
||||
@@ -177,27 +177,29 @@ public class DataTypePreviewPlugin extends ProgramPlugin {
|
||||
|
||||
private void updateModel() {
|
||||
|
||||
LayeredDataTypeManager newDtm = new LayeredDataTypeManager(activeProgram);
|
||||
|
||||
int transactionId = newDtm.startTransaction("add datatypes");
|
||||
try {
|
||||
Iterator<DataType> allDataTypes = dataTypeManager.getAllDataTypes();
|
||||
while (allDataTypes.hasNext()) {
|
||||
newDtm.resolve(allDataTypes.next(), null);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
newDtm.endTransaction(transactionId, true);
|
||||
}
|
||||
|
||||
// NOTE: data types do not respond to switching the data organization object
|
||||
// since this is cached internal to the data type at time of construction.
|
||||
// We must purge old datatypes and have them re-instantiated by the
|
||||
// datatype manager
|
||||
List<DataTypePath> dtPaths = getModelDataTypePaths();
|
||||
model.removeAll();
|
||||
dataTypeManager.invalidate();
|
||||
|
||||
int transactionId = dataTypeManager.startTransaction("realign");
|
||||
try {
|
||||
Iterator<Composite> allComposites = dataTypeManager.getAllComposites();
|
||||
while (allComposites.hasNext()) {
|
||||
Composite composite = allComposites.next();
|
||||
if (composite.isInternallyAligned()) {
|
||||
composite.realign();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
dataTypeManager.endTransaction(transactionId, true);
|
||||
}
|
||||
LayeredDataTypeManager oldDtm = dataTypeManager;
|
||||
dataTypeManager = newDtm;
|
||||
oldDtm.close();
|
||||
|
||||
for (DataTypePath dtPath : dtPaths) {
|
||||
DataType dataType = dataTypeManager.getDataType(dtPath);
|
||||
@@ -538,14 +540,11 @@ public class DataTypePreviewPlugin extends ProgramPlugin {
|
||||
}
|
||||
|
||||
private void add(Composite c, DataTypeComponentPreview parent) {
|
||||
DataTypeComponent[] comps = c.getComponents();
|
||||
DataTypeComponent[] comps = c.getDefinedComponents();
|
||||
for (DataTypeComponent element : comps) {
|
||||
DataTypeComponentPreview preview = new DataTypeComponentPreview(c, element);
|
||||
preview.setParent(parent);
|
||||
DataType dataType = element.getDataType();
|
||||
if (dataType == DataType.DEFAULT) {
|
||||
continue;
|
||||
}
|
||||
if (dataType instanceof Composite) {
|
||||
add((Composite) element.getDataType(), preview);
|
||||
}
|
||||
@@ -714,21 +713,22 @@ public class DataTypePreviewPlugin extends ProgramPlugin {
|
||||
|
||||
private class LayeredDataTypeManager extends StandAloneDataTypeManager {
|
||||
|
||||
public LayeredDataTypeManager() {
|
||||
DataOrganization layeredDataOrganization1;
|
||||
|
||||
public LayeredDataTypeManager(Program program) {
|
||||
super("DataTypePreviewer");
|
||||
this.layeredDataOrganization1 =
|
||||
program != null ? program.getDataTypeManager().getDataOrganization() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataOrganization getDataOrganization() {
|
||||
if (currentProgram != null) {
|
||||
return currentProgram.getDataTypeManager().getDataOrganization();
|
||||
if (layeredDataOrganization1 == null) {
|
||||
return super.getDataOrganization();
|
||||
}
|
||||
return super.getDataOrganization();
|
||||
}
|
||||
|
||||
void invalidate() {
|
||||
invalidateCache();
|
||||
return layeredDataOrganization1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.stackeditor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.*;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
@@ -54,6 +55,49 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
this.splitOffset = splitOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlignment() {
|
||||
throw new UnsupportedOperationException(
|
||||
"BiDirectionDataType.getAlignment() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean repack(boolean notify) {
|
||||
throw new AssertException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToDefaultAligned() {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToMachineAligned() {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPackingEnabled(boolean aligned) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExplicitPackingValue(int packingValue) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExplicitMinimumAlignment(int minimumAlignment) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataTypeComponent setFlexibleArrayComponent(DataType flexType, String name,
|
||||
String comment) {
|
||||
throw new UnsupportedOperationException(
|
||||
"BiDirectionDataType.setFlexibleArrayComponent() not implemented.");
|
||||
}
|
||||
|
||||
protected DataTypeComponent getDefinedComponentAt(int offset) {
|
||||
if (offset < splitOffset - negativeLength || offset >= splitOffset + positiveLength) {
|
||||
return null;
|
||||
@@ -108,20 +152,15 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
return positiveLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return structLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(int index) {
|
||||
if (index < 0 || index >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
throw new IndexOutOfBoundsException(index);
|
||||
}
|
||||
DataTypeComponent comp = getComponent(index);
|
||||
int offset = comp.getOffset();
|
||||
int length = comp.getLength();
|
||||
int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
int idx = Collections.binarySearch(components, index, ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
DataTypeComponent dtc = components.remove(idx);
|
||||
dtc.getDataType().removeParent(this);
|
||||
@@ -137,7 +176,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(int[] ordinals) {
|
||||
public void delete(Set<Integer> ordinals) {
|
||||
for (int ordinal : ordinals) {
|
||||
delete(ordinal);
|
||||
}
|
||||
@@ -173,6 +212,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
}
|
||||
}
|
||||
structLength += deltaLength;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -198,7 +238,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
|
||||
protected DataTypeComponent getDefinedComponent(int ordinal) {
|
||||
if (ordinal < 0 || ordinal >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(ordinal);
|
||||
throw new IndexOutOfBoundsException(ordinal);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
@@ -210,7 +250,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
@Override
|
||||
public DataTypeComponent getComponent(int ordinal) {
|
||||
if (ordinal < 0 || ordinal >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(ordinal);
|
||||
throw new IndexOutOfBoundsException(ordinal);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
@@ -255,12 +295,14 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
numComponents += deltaLength;
|
||||
positiveLength += deltaLength;
|
||||
structLength += deltaLength;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
}
|
||||
if (nextOffset < splitOffset - negativeLength) {
|
||||
int deltaLength = splitOffset - nextOffset - negativeLength;
|
||||
numComponents += deltaLength;
|
||||
negativeLength += deltaLength;
|
||||
structLength += deltaLength;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
}
|
||||
checkAncestry(dataType);
|
||||
dataType = dataType.clone(getDataTypeManager());
|
||||
@@ -319,6 +361,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
numComponents++;
|
||||
positiveLength += length;
|
||||
structLength += length;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
notifySizeChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -341,6 +384,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
numComponents++;
|
||||
negativeLength += length;
|
||||
structLength += length;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
notifySizeChanged();
|
||||
return dtc;
|
||||
}
|
||||
@@ -367,39 +411,14 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
}
|
||||
numComponents += absAmount;
|
||||
structLength += absAmount;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
notifySizeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataTypeComponent insert(int index, DataType dataType, int length, String newName,
|
||||
String comment) {
|
||||
throw new AssertException("BiDirectionDataType.insert() not implemented.");
|
||||
// if (index < 0 || index > numComponents) {
|
||||
// throw new ArrayIndexOutOfBoundsException(index);
|
||||
// }
|
||||
// if (index == numComponents) {
|
||||
// return add(dataType, length, newName, comment);
|
||||
// }
|
||||
// validateDataType(dataType);
|
||||
//
|
||||
// dataType = resolve(dataType);
|
||||
// checkAncestry(dataType);
|
||||
//
|
||||
// int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
// if (idx < 0) {
|
||||
// idx = -idx -1;
|
||||
// }
|
||||
// if (dataType == DataType.DEFAULT) {
|
||||
// shiftOffsets(idx, 1, 1);
|
||||
// return getComponent(index);
|
||||
// }
|
||||
// int offset = ((DataTypeComponent)getComponent(index)).getOffset();
|
||||
// DataTypeComponent dtc = new DataTypeComponentImpl(dataType,this, length,index,
|
||||
// offset, newName, comment);
|
||||
// shiftOffsets(idx, 1, dtc.getLength());
|
||||
// components.add(idx, dtc);
|
||||
// sizeChanged();
|
||||
// return dtc;
|
||||
throw new UnsupportedOperationException("BiDirectionDataType.insert() not implemented.");
|
||||
}
|
||||
|
||||
protected void insertAtOffset(int offset, int numBytes) {
|
||||
@@ -441,6 +460,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
}
|
||||
numComponents += numBytes;
|
||||
structLength += numBytes;
|
||||
// nonpackedAlignedStructLength = -1;
|
||||
notifySizeChanged();
|
||||
}
|
||||
|
||||
@@ -479,7 +499,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
if ((splitOffset != biDir.getSplitOffset()) ||
|
||||
(negativeLength != biDir.getNegativeLength()) ||
|
||||
(positiveLength != biDir.getPositiveLength()) ||
|
||||
(structLength != biDir.getLength())) {
|
||||
(getLength() != biDir.getLength())) {
|
||||
return false;
|
||||
}
|
||||
DataTypeComponent[] myComps = getDefinedComponents();
|
||||
@@ -499,72 +519,13 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
|
||||
@Override
|
||||
public void dataTypeSizeChanged(DataType dt) {
|
||||
throw new AssertException("BiDirectionDataType.dataTypeSizeChanged() not implemented.");
|
||||
// int n = components.size();
|
||||
// boolean didChange = false;
|
||||
// for(int i=0;i<n;i++) {
|
||||
// DataTypeComponentImpl dtc = (DataTypeComponentImpl)components.get(i);
|
||||
// if (dtc.getDataType() == dt) {
|
||||
// int dtLen = dt.getLength();
|
||||
// int dtcLen = dtc.getLength();
|
||||
// if (dtLen < dtcLen) {
|
||||
// dtc.setLength(dtLen);
|
||||
// shiftOffsets(i+1, dtcLen-dtLen, 0);
|
||||
// didChange = true;
|
||||
// }
|
||||
// else if (dtLen > dtcLen) {
|
||||
// int consumed = consumeBytesAfter(i, dtLen-dtcLen);
|
||||
// if (consumed > 0) {
|
||||
// shiftOffsets(i+1, 0-consumed, 0);
|
||||
// didChange = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (didChange & dtMgr != null) {
|
||||
// dtMgr.dataTypeChanged(this);
|
||||
// }
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param index the index of the defined component that is consuming the bytes.
|
||||
* @param numBytes the number of undefined bytes to consume
|
||||
* @return the number of bytes actually consumed
|
||||
*/
|
||||
// private int consumeBytesAfter(int index, int numBytes) {
|
||||
// throw new AssertException("BiDirectionDataType.consumeBytesAfter() not implemented.");
|
||||
// DataTypeComponentImpl thisDtc = (DataTypeComponentImpl)components.get(index);
|
||||
// int thisLen = thisDtc.getLength();
|
||||
// int nextOffset = thisDtc.getOffset()+thisLen;
|
||||
// int available = structLength-nextOffset;
|
||||
// if (index+1 < components.size()) {
|
||||
// DataTypeComponent nextDtc = (DataTypeComponent)components.get(index+1);
|
||||
// available = nextDtc.getOffset() - nextOffset;
|
||||
// }
|
||||
// else {
|
||||
// available = structLength-nextOffset;
|
||||
// }
|
||||
// if (numBytes <= available) {
|
||||
// thisDtc.setLength(thisLen + numBytes);
|
||||
// return numBytes;
|
||||
// }
|
||||
// else {
|
||||
// thisDtc.setLength(thisLen + available);
|
||||
// return available;
|
||||
// }
|
||||
// }
|
||||
|
||||
// private boolean hasRoom(int index, int offset, int length) {
|
||||
// if (offset+length > this.positiveLength) {
|
||||
// return false;
|
||||
// }
|
||||
// if (index+1 < components.size()) {
|
||||
// DataTypeComponent nextDtc = (DataTypeComponent)components.get(index+1);
|
||||
// return offset+length <= nextDtc.getOffset();
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
@Override
|
||||
public void dataTypeAlignmentChanged(DataType dt) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract BiDirectionDataType clone(DataTypeManager dtm);
|
||||
@@ -572,7 +533,7 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
@Override
|
||||
public void clearComponent(int index) {
|
||||
if (index < 0 || index >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
throw new IndexOutOfBoundsException(index);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
@@ -589,81 +550,20 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
}
|
||||
|
||||
public void replaceWith(Structure struct) {
|
||||
throw new AssertException("BiDirectionDataType.replaceWith() not implemented.");
|
||||
// int oldLength = structLength;
|
||||
// doReplaceWith(struct);
|
||||
// if (oldLength != structLength) {
|
||||
// sizeChanged();
|
||||
// }
|
||||
// else if (dtMgr != null) {
|
||||
// dtMgr.dataTypeChanged(this);
|
||||
// }
|
||||
throw new UnsupportedOperationException(
|
||||
"BiDirectionDataType.replaceWith() not implemented.");
|
||||
}
|
||||
|
||||
// private void doReplaceWith(Structure struct) {
|
||||
// throw new AssertException("BiDirectionDataType.doReplaceWith() not implemented.");
|
||||
// components.clear();
|
||||
// structLength = struct.getLength();
|
||||
// numComponents = structLength;
|
||||
//
|
||||
// DataTypeComponent[] components = struct.getDefinedComponents();
|
||||
// for(int i=0;i<components.length;i++) {
|
||||
// DataTypeComponent dtc = components[i];
|
||||
// DataType dt = dtc.getDataType();
|
||||
// validateDataType(dt);
|
||||
// dt = resolve(dt);
|
||||
// replaceAtOffset(dtc.getOffset(), dt, dtc.getLength(),
|
||||
// dtc.getFieldName(), dtc.getComment());
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void dataTypeDeleted(DataType dt) {
|
||||
throw new AssertException("BiDirectionDataType.dataTypeDeleted() not implemented.");
|
||||
// boolean didChange = false;
|
||||
// int n = components.size();
|
||||
// for(int i=n-1;i>=0;i--) {
|
||||
// DataTypeComponentImpl dtc = (DataTypeComponentImpl)components.get(i);
|
||||
// if (dtc.getDataType() == dt) {
|
||||
// components.remove(i);
|
||||
// shiftOffsets(i, dtc.getLength()-1, 0);
|
||||
// didChange = true;
|
||||
// }
|
||||
// }
|
||||
// if (didChange && dtMgr != null) {
|
||||
// dtMgr.dataTypeChanged(this);
|
||||
// }
|
||||
|
||||
throw new UnsupportedOperationException(
|
||||
"BiDirectionDataType.dataTypeDeleted() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
||||
throw new AssertException("BiDirectionDataType.dataTypeReplaced() not implemented.");
|
||||
// int n = components.size();
|
||||
// boolean didChange = false;
|
||||
// for(int i=0;i<n;i++) {
|
||||
// DataTypeComponentImpl dtc = (DataTypeComponentImpl)components.get(i);
|
||||
// if (dtc.getDataType() == oldDt) {
|
||||
// int dtLen = oldDt.getLength();
|
||||
// int dtcLen = dtc.getLength();
|
||||
// dtc.setDataType(newDt);
|
||||
// if (dtLen < dtcLen) {
|
||||
// dtc.setLength(dtLen);
|
||||
// shiftOffsets(i+1, dtcLen-dtLen, 0);
|
||||
// didChange = true;
|
||||
// }
|
||||
// else if (dtLen > dtcLen) {
|
||||
// int consumed = consumeBytesAfter(i, dtLen-dtcLen);
|
||||
// if (consumed > 0) {
|
||||
// shiftOffsets(i+1, 0-consumed, 0);
|
||||
// didChange = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (didChange & dtMgr != null) {
|
||||
// dtMgr.dataTypeChanged(this);
|
||||
// }
|
||||
throw new UnsupportedOperationException(
|
||||
"BiDirectionDataType.dataTypeReplaced() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -682,9 +582,9 @@ public abstract class BiDirectionDataType extends StructureDataType
|
||||
|
||||
@Override
|
||||
public DataTypeComponent replace(int index, DataType dataType, int length, String newName,
|
||||
String comment) throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
|
||||
String comment) throws IndexOutOfBoundsException, IllegalArgumentException {
|
||||
if (index < 0 || index >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
throw new IndexOutOfBoundsException(index);
|
||||
}
|
||||
validateDataType(dataType);
|
||||
checkAncestry(dataType);
|
||||
|
||||
@@ -68,8 +68,7 @@ public class StackFrameDataType extends BiDirectionDataType {
|
||||
this.returnAddressOffset = stackDt.returnAddressOffset;
|
||||
this.stack = stackDt.stack;
|
||||
this.defaultSettings = stackDt.defaultSettings;
|
||||
for (int i = 0; i < stackDt.components.size(); i++) {
|
||||
DataTypeComponent dtc = stackDt.components.get(i);
|
||||
for (DataTypeComponentImpl dtc : stackDt.components) {
|
||||
replaceAtOffset(dtc.getOffset(), dtc.getDataType(), dtc.getLength(), dtc.getFieldName(),
|
||||
dtc.getComment());
|
||||
}
|
||||
@@ -216,7 +215,7 @@ public class StackFrameDataType extends BiDirectionDataType {
|
||||
* @see ghidra.program.model.listing.StackFrame#getFrameSize()
|
||||
*/
|
||||
public int getFrameSize() {
|
||||
return structLength;
|
||||
return getLength();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -261,8 +260,9 @@ public class StackFrameDataType extends BiDirectionDataType {
|
||||
}
|
||||
|
||||
private boolean adjustStackFrameSize(int newSize, int oldSize, boolean isNegative) {
|
||||
if (newSize < 0)
|
||||
if (newSize < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int delta = newSize - oldSize;
|
||||
if (delta == 0) {
|
||||
|
||||
@@ -82,8 +82,7 @@ class DWARFDataTypeConflictHandler extends DataTypeConflictHandler {
|
||||
* @return true if empty or default and false otherwise
|
||||
*/
|
||||
private boolean isCompositeDefault(Composite composite) {
|
||||
return composite.isNotYetDefined()
|
||||
|| ((composite instanceof Structure) && ((Structure) composite).getNumDefinedComponents() == 0);
|
||||
return composite.isNotYetDefined() || (composite.getNumDefinedComponents() == 0);
|
||||
}
|
||||
|
||||
private boolean isCompositePart(Composite full, Composite part, Set<Long> visitedDataTypes) {
|
||||
|
||||
@@ -85,8 +85,10 @@ public class MSDataTypeUtils {
|
||||
CategoryPath categoryPath, String structureName, int packValue) {
|
||||
StructureDataType struct =
|
||||
new StructureDataType(categoryPath, structureName, 0, dataTypeManager);
|
||||
struct.setInternallyAligned(true);
|
||||
struct.setPackingValue(packValue);
|
||||
struct.setPackingEnabled(true);
|
||||
if (packValue > 0) {
|
||||
struct.setExplicitPackingValue(packValue);
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.util.html;
|
||||
|
||||
import static ghidra.util.HTMLUtilities.friendlyEncodeHTML;
|
||||
import static ghidra.util.HTMLUtilities.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.*;
|
||||
@@ -77,7 +77,7 @@ public class CompositeDataTypeHTMLRepresentation extends HTMLDataTypeRepresentat
|
||||
}
|
||||
|
||||
protected List<String> buildWarnings(Composite comp) {
|
||||
if (!comp.isNotYetDefined()) {
|
||||
if (!comp.isZeroLength()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
@@ -87,7 +87,7 @@ public class CompositeDataTypeHTMLRepresentation extends HTMLDataTypeRepresentat
|
||||
|
||||
@Override
|
||||
protected TextLine buildFooterText(DataType dataType) {
|
||||
if (dataType.isNotYetDefined()) {
|
||||
if (dataType.isZeroLength()) {
|
||||
return new TextLine("0");
|
||||
}
|
||||
return super.buildFooterText(dataType);
|
||||
@@ -95,44 +95,24 @@ public class CompositeDataTypeHTMLRepresentation extends HTMLDataTypeRepresentat
|
||||
|
||||
protected List<ValidatableLine> buildAlignmentText(Composite dataType) {
|
||||
List<ValidatableLine> list = new ArrayList<>();
|
||||
if (!dataType.isInternallyAligned()) {
|
||||
list.add(new TextLine("unaligned"));
|
||||
String alignStr = CompositeDataTypeImpl.getMinAlignmentString(dataType);
|
||||
if (alignStr != null && alignStr.length() != 0) {
|
||||
list.add(new TextLine(alignStr));
|
||||
}
|
||||
else if (dataType.isDefaultAligned()) {
|
||||
list.add(new TextLine("align()"));
|
||||
}
|
||||
else if (dataType.isMachineAligned()) {
|
||||
list.add(new TextLine("align(machine)"));
|
||||
}
|
||||
else {
|
||||
long alignment = dataType.getMinimumAlignment();
|
||||
list.add(new TextLine("align(" + alignment + ")"));
|
||||
}
|
||||
TextLine packingText = buildPackingText(dataType);
|
||||
if (packingText != null) {
|
||||
list.add(packingText);
|
||||
String packStr = CompositeDataTypeImpl.getPackingString(dataType);
|
||||
if (packStr != null && packStr.length() != 0) {
|
||||
list.add(new TextLine(packStr));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected TextLine buildPackingText(Composite dataType) {
|
||||
if (!dataType.isInternallyAligned()) {
|
||||
return null;
|
||||
}
|
||||
long packingValue = dataType.getPackingValue();
|
||||
if (packingValue == Composite.NOT_PACKING) {
|
||||
return null;
|
||||
}
|
||||
return new TextLine(" pack(" + packingValue + ")");
|
||||
}
|
||||
|
||||
protected TextLine buildAlignmentValueText(Composite composite) {
|
||||
return new TextLine("" + composite.getAlignment());
|
||||
}
|
||||
|
||||
private List<ValidatableLine> buildContent(Composite comp) {
|
||||
List<ValidatableLine> list = new ArrayList<>();
|
||||
if (comp.isNotYetDefined()) {
|
||||
if (comp.isZeroLength()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class TypeDefDataTypeHTMLRepresentation extends HTMLDataTypeRepresentatio
|
||||
|
||||
protected List<String> buildWarnings() {
|
||||
DataType baseType = typeDef.getBaseDataType();
|
||||
if (!(baseType instanceof Composite) || !baseType.isNotYetDefined()) {
|
||||
if (!(baseType instanceof Composite) || !baseType.isZeroLength()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
@@ -81,7 +81,7 @@ public class TypeDefDataTypeHTMLRepresentation extends HTMLDataTypeRepresentatio
|
||||
|
||||
@Override
|
||||
protected TextLine buildFooterText(DataType dataType) {
|
||||
if (dataType.isNotYetDefined()) {
|
||||
if (dataType.isZeroLength()) {
|
||||
return new TextLine("0");
|
||||
}
|
||||
return super.buildFooterText(dataType);
|
||||
|
||||
@@ -292,7 +292,7 @@ public class BytesFieldFactory extends FieldFactory {
|
||||
return null; // e.g., union
|
||||
}
|
||||
Structure struct = (Structure) baseDataType;
|
||||
if (!struct.isInternallyAligned()) {
|
||||
if (!struct.isPackingEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -623,7 +623,7 @@ public class DataTypesXmlMgr {
|
||||
XmlAttributes attrs = new XmlAttributes();
|
||||
attrs.addAttribute("NAME", struct.getDisplayName());
|
||||
attrs.addAttribute("NAMESPACE", struct.getCategoryPath().getPath());
|
||||
attrs.addAttribute("SIZE", struct.isNotYetDefined() ? 0 : struct.getLength(), true);
|
||||
attrs.addAttribute("SIZE", struct.isZeroLength() ? 0 : struct.getLength(), true);
|
||||
writer.startElement("STRUCTURE", attrs);
|
||||
writeRegularComment(writer, struct.getDescription());
|
||||
DataTypeComponent[] members = struct.getComponents();
|
||||
@@ -637,7 +637,7 @@ public class DataTypesXmlMgr {
|
||||
XmlAttributes attrs = new XmlAttributes();
|
||||
attrs.addAttribute("NAME", union.getDisplayName());
|
||||
attrs.addAttribute("NAMESPACE", union.getCategoryPath().getPath());
|
||||
attrs.addAttribute("SIZE", union.isNotYetDefined() ? 0 : union.getLength(), true);
|
||||
attrs.addAttribute("SIZE", union.isZeroLength() ? 0 : union.getLength(), true);
|
||||
writer.startElement("UNION", attrs);
|
||||
writeRegularComment(writer, union.getDescription());
|
||||
DataTypeComponent[] members = union.getComponents();
|
||||
@@ -649,7 +649,7 @@ public class DataTypesXmlMgr {
|
||||
|
||||
private void writerMember(XmlWriter writer, DataTypeComponent member) {
|
||||
XmlAttributes attrs = new XmlAttributes();
|
||||
// TODO: how should we output bitfields (aligned/unaligned) and flex array
|
||||
// TODO: how should we output bitfields (packed/non-packed) and flex array
|
||||
attrs.addAttribute("OFFSET", member.getOffset(), true);
|
||||
attrs.addAttribute("DATATYPE", member.getDataType().getDisplayName());
|
||||
attrs.addAttribute("DATATYPE_NAMESPACE", member.getDataType().getCategoryPath().getPath());
|
||||
|
||||
@@ -1675,17 +1675,25 @@ Composite StructOrUnion() : {Composite comp;}
|
||||
(
|
||||
<STRUCT> ( DeclSpec() )* { comp = new StructureDataType(ANONYMOUS_STRUCT_PREFIX + cnt++, 0);
|
||||
|
||||
// Always set the packing, because by default structures should be aligned
|
||||
// setting 0 turns off packing, but sets structures to be aligned
|
||||
comp.setPackingValue(this.packSize);
|
||||
// Always set the packing, because by default structures should be aligned
|
||||
if (packSize > 0) {
|
||||
comp.setExplicitPackingValue(packSize);
|
||||
}
|
||||
else {
|
||||
comp.setPackingEnabled(true); // ensure default packing enabled
|
||||
}
|
||||
|
||||
}
|
||||
|
|
||||
<UNION> ( DeclSpec() )* { comp = new UnionDataType(ANONYMOUS_UNION_PREFIX + cnt++);
|
||||
|
||||
// Always set the packing, because by default structures should be aligned
|
||||
// setting 0 turns off packing, but sets structures to be aligned.
|
||||
comp.setPackingValue(this.packSize);
|
||||
if (packSize > 0) {
|
||||
comp.setExplicitPackingValue(packSize);
|
||||
}
|
||||
else {
|
||||
comp.setPackingEnabled(true); // ensure default packing enabled
|
||||
}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
@@ -604,7 +604,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||
|
||||
executeMerge();
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose My Bar
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose My Bar // TODO: I see no reason for a conflict !
|
||||
|
||||
setErrorsExpected(true);
|
||||
|
||||
@@ -2201,7 +2201,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"Unaligned\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 null \"\"\n" +
|
||||
" 0 byte:4(4) 1 BF1 \"my bf1\"\n" +
|
||||
|
||||
@@ -27,7 +27,7 @@ import ghidra.program.database.ProgramModifierListener;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* More data type merge tests.
|
||||
@@ -502,7 +502,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
int transactionID = program.startTransaction("test");
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
try {
|
||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -709,7 +709,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
// delete Bar from Foo
|
||||
fs.delete(3);
|
||||
// add Foo to Bar
|
||||
dtm.remove(bs, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bs, TaskMonitor.DUMMY);
|
||||
|
||||
// Add s1, s2, s3
|
||||
Structure s1 = new StructureDataType(new CategoryPath("/MISC"), "S1", 0);
|
||||
@@ -809,7 +809,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
// delete Bar from Foo
|
||||
foo.delete(3);
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
|
||||
// Add s1, s2, s3
|
||||
Structure s1 = new StructureDataType(new CategoryPath("/MISC"), "S1", 0);
|
||||
@@ -920,7 +920,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
// delete Bar from Foo
|
||||
fs.delete(3);
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bs, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bs, TaskMonitor.DUMMY);
|
||||
|
||||
// Add s1, s2, s3
|
||||
Structure s1 = new StructureDataType(new CategoryPath("/MISC"), "S1", 0);
|
||||
@@ -1034,7 +1034,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure fs = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
try {
|
||||
// delete Foo from the data type manager
|
||||
dtm.remove(fs, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(fs, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1051,7 +1051,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// delete Foo from the data type manager
|
||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||
|
||||
// Add s1, s2, s3
|
||||
Structure s1 = new StructureDataType(new CategoryPath("/MISC"), "S1", 0);
|
||||
@@ -1129,7 +1129,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure fs = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
try {
|
||||
// delete Foo from the data type manager
|
||||
dtm.remove(fs, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(fs, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1146,7 +1146,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// delete Foo from the data type manager
|
||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||
|
||||
// Add s1, s2, s3
|
||||
Structure s1 = new StructureDataType(new CategoryPath("/MISC"), "S1", 0);
|
||||
@@ -1318,7 +1318,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1441,7 +1441,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1555,7 +1555,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1643,7 +1643,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1750,7 +1750,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1844,7 +1844,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
@@ -1943,7 +1943,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
try {
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
|
||||