mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
BitFields - improved unaligned structure edit behavior
This commit is contained in:
parent
31163bca26
commit
d4ea232a4d
5 changed files with 121 additions and 43 deletions
|
@ -255,7 +255,17 @@ public class BitFieldPlacementComponent extends JPanel {
|
|||
CompositeChangeListener listener) {
|
||||
HashSet<Integer> ordinalDeleteSet = new HashSet<>();
|
||||
if (editOrdinal >= 0) {
|
||||
int initialLength = composite.getLength();
|
||||
|
||||
composite.delete(editOrdinal);
|
||||
|
||||
int sizeChange = initialLength - composite.getLength();
|
||||
if (!composite.isInternallyAligned() && editOrdinal < composite.getNumComponents()) {
|
||||
// deletions cause shift which is bad - pad with defaults
|
||||
for (int i = 0; i < sizeChange; i++) {
|
||||
composite.insert(editOrdinal, DataType.DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (deleteConflicts) {
|
||||
for (BitAttributes attrs : bitFieldAllocation.bitAttributes) {
|
||||
|
|
|
@ -1238,4 +1238,5 @@ public abstract class CompositeEditorModel extends CompositeViewerModel implemen
|
|||
protected boolean bitfieldsSupported() {
|
||||
return (viewComposite instanceof Structure) || (viewComposite instanceof Union);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,13 +23,12 @@ import javax.swing.KeyStroke;
|
|||
|
||||
import docking.ActionContext;
|
||||
import docking.action.KeyBindingData;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeInstance;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.UsrException;
|
||||
import resources.ResourceManager;
|
||||
|
||||
/**
|
||||
* Action for use in the composite data type editor.
|
||||
* Action for use in the structure data type editor.
|
||||
* This action has help associated with it.
|
||||
*/
|
||||
public class InsertUndefinedAction extends CompositeEditorTableAction {
|
||||
|
@ -57,8 +56,10 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
|||
if (isContiguousSelection) {
|
||||
int index = model.getMinIndexSelected();
|
||||
if (index >= 0) {
|
||||
DataTypeInstance dti =
|
||||
DataTypeInstance.getDataTypeInstance(DataType.DEFAULT, 1);
|
||||
DataType undefinedDt =
|
||||
model.viewComposite.isInternallyAligned() ? Undefined1DataType.dataType
|
||||
: DataType.DEFAULT;
|
||||
DataTypeInstance dti = DataTypeInstance.getDataTypeInstance(undefinedDt, -1);
|
||||
model.insert(index, dti.getDataType(), dti.getLength());
|
||||
}
|
||||
}
|
||||
|
@ -71,13 +72,16 @@ public class InsertUndefinedAction extends CompositeEditorTableAction {
|
|||
|
||||
@Override
|
||||
public void adjustEnablement() {
|
||||
if (model.viewComposite == null) {
|
||||
return;
|
||||
boolean enabled = false;
|
||||
if (model.viewComposite instanceof Structure) {
|
||||
boolean isContiguousSelection = model.getSelection().getNumRanges() == 1;
|
||||
DataType undefinedDt =
|
||||
model.viewComposite.isInternallyAligned() ? Undefined1DataType.dataType
|
||||
: DataType.DEFAULT;
|
||||
enabled = isContiguousSelection &&
|
||||
model.isInsertAllowed(model.getMinIndexSelected(), undefinedDt);
|
||||
}
|
||||
boolean isContiguousSelection = model.getSelection().getNumRanges() == 1;
|
||||
|
||||
setEnabled(isContiguousSelection && model.isShowingUndefinedBytes() &&
|
||||
model.isInsertAllowed(model.getMinIndexSelected(), DataType.DEFAULT));
|
||||
setEnabled(enabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -229,7 +229,20 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
// TODO: could improve insertion of bitfield which does not intersect
|
||||
// existing ordinal bitfield at the bit-level
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
if (idx > 0) {
|
||||
DataTypeComponentDB existingDtc = components.get(idx);
|
||||
if (existingDtc.isBitFieldComponent()) {
|
||||
// must shift down to eliminate possible overlap with previous component
|
||||
DataTypeComponentDB previousDtc = components.get(idx - 1);
|
||||
if (previousDtc.getEndOffset() == existingDtc.getOffset()) {
|
||||
shiftOffsets(idx, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
|
@ -331,7 +344,7 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
|
||||
Comparator<Object> bitOffsetComparator =
|
||||
bigEndian ? bitOffsetComparatorBE : bitOffsetComparatorLE;
|
||||
int startIndex = Collections.binarySearch(components, new Integer(startBitOffset),
|
||||
int startIndex = Collections.binarySearch(components, Integer.valueOf(startBitOffset),
|
||||
bitOffsetComparator);
|
||||
if (startIndex < 0) {
|
||||
startIndex = -startIndex - 1;
|
||||
|
@ -437,7 +450,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
doDelete(idx);
|
||||
|
@ -467,10 +481,25 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
if (isInternallyAligned()) {
|
||||
return;
|
||||
}
|
||||
int shiftAmount = 0;
|
||||
// Bitfields: do not remove space previously occupied
|
||||
if (!dtc.isBitFieldComponent()) {
|
||||
shiftAmount = dtc.getLength();
|
||||
int shiftAmount = dtc.getLength();
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
// Must handle potential overlap with adjacent components
|
||||
// NOTE: existing bitfields will not overlap by more than one byte
|
||||
int minOffset = dtc.getOffset();
|
||||
int maxOffset = dtc.getEndOffset();
|
||||
if (index > 0) {
|
||||
DataTypeComponentDB previousDtc = components.get(index - 1);
|
||||
if (previousDtc.getEndOffset() == dtc.getOffset()) {
|
||||
++minOffset;
|
||||
}
|
||||
}
|
||||
if (minOffset <= maxOffset && index < components.size()) {
|
||||
DataTypeComponentDB nextDtc = components.get(index);
|
||||
if (nextDtc.getOffset() == dtc.getOffset()) {
|
||||
--maxOffset;
|
||||
}
|
||||
}
|
||||
shiftAmount = maxOffset - minOffset + 1;
|
||||
}
|
||||
shiftOffsets(index, -1, -shiftAmount);
|
||||
}
|
||||
|
@ -498,7 +527,7 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal),
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
|
@ -582,7 +611,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
if (isInternallyAligned()) {
|
||||
return components.get(ordinal);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
int idx =
|
||||
Collections.binarySearch(components, Integer.valueOf(ordinal), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
return components.get(idx);
|
||||
}
|
||||
|
@ -684,7 +714,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
DataTypeComponentDB dtc = components.remove(idx);
|
||||
|
@ -766,7 +797,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
if (offset >= structLength) {
|
||||
return;
|
||||
}
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index =
|
||||
Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
|
||||
int offsetDelta = 0;
|
||||
int ordinalDelta = 0;
|
||||
|
@ -804,7 +836,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
if (offset >= structLength || offset < 0) {
|
||||
return null;
|
||||
}
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index =
|
||||
Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
if (index >= 0) {
|
||||
DataTypeComponent dtc = components.get(index);
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
|
@ -883,7 +916,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
structLength = offset;
|
||||
}
|
||||
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index =
|
||||
Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
|
||||
int additionalShift = 0;
|
||||
if (index >= 0) {
|
||||
|
@ -1418,8 +1452,8 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
index = ordinal;
|
||||
}
|
||||
else {
|
||||
index =
|
||||
Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
index = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
}
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
|
@ -1465,7 +1499,7 @@ class StructureDB extends CompositeDB implements Structure {
|
|||
if (ordinal >= numComponents) {
|
||||
return 0;
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
int idx = Collections.binarySearch(components, Integer.valueOf(ordinal), ordinalComparator);
|
||||
DataTypeComponentDB dtc = null;
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
|
|
|
@ -122,7 +122,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (offset >= structLength || offset < 0) {
|
||||
return null;
|
||||
}
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index = Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
if (index >= 0) {
|
||||
DataTypeComponent dtc = components.get(index);
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
|
@ -173,7 +173,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal), ordinalComparator);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
doDelete(idx);
|
||||
|
@ -193,10 +193,25 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (isInternallyAligned()) {
|
||||
return;
|
||||
}
|
||||
int shiftAmount = 0;
|
||||
// Bitfields: do not remove space previously occupied
|
||||
if (!dtc.isBitFieldComponent()) {
|
||||
shiftAmount = dtc.getLength();
|
||||
int shiftAmount = dtc.getLength();
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
// Must handle potential overlap with adjacent components
|
||||
// NOTE: existing bitfields will not overlap by more than one byte
|
||||
int minOffset = dtc.getOffset();
|
||||
int maxOffset = dtc.getEndOffset();
|
||||
if (index > 0) {
|
||||
DataTypeComponentImpl previousDtc = components.get(index - 1);
|
||||
if (previousDtc.getEndOffset() == dtc.getOffset()) {
|
||||
++minOffset;
|
||||
}
|
||||
}
|
||||
if (minOffset <= maxOffset && index < components.size()) {
|
||||
DataTypeComponentImpl nextDtc = components.get(index);
|
||||
if (nextDtc.getOffset() == dtc.getOffset()) {
|
||||
--maxOffset;
|
||||
}
|
||||
}
|
||||
shiftAmount = maxOffset - minOffset + 1;
|
||||
}
|
||||
shiftOffsets(index, -1, -shiftAmount);
|
||||
}
|
||||
|
@ -222,7 +237,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
idx = ordinal;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(ordinal),
|
||||
ordinalComparator);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
doDelete(idx);
|
||||
|
@ -259,7 +275,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (index < 0 || index >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
int idx = Collections.binarySearch(components, Integer.valueOf(index), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
return components.get(idx);
|
||||
}
|
||||
|
@ -308,7 +324,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
structLength = offset;
|
||||
}
|
||||
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index = Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
|
||||
int additionalShift = 0;
|
||||
if (index >= 0) {
|
||||
|
@ -448,7 +464,19 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
idx = index;
|
||||
}
|
||||
else {
|
||||
idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
// TODO: could improve insertion of bitfield which does not intersect
|
||||
// existing ordinal bitfield at the bit-level
|
||||
idx = Collections.binarySearch(components, Integer.valueOf(index), ordinalComparator);
|
||||
if (idx > 0) {
|
||||
DataTypeComponentImpl existingDtc = components.get(idx);
|
||||
if (existingDtc.isBitFieldComponent()) {
|
||||
// must shift down to eliminate possible overlap with previous component
|
||||
DataTypeComponentImpl previousDtc = components.get(idx - 1);
|
||||
if (previousDtc.getEndOffset() == existingDtc.getOffset()) {
|
||||
shiftOffsets(idx, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
|
@ -533,8 +561,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
|
||||
Comparator<Object> bitOffsetComparator =
|
||||
bigEndian ? bitOffsetComparatorBE : bitOffsetComparatorLE;
|
||||
int startIndex =
|
||||
Collections.binarySearch(components, new Integer(startBitOffset), bitOffsetComparator);
|
||||
int startIndex = Collections.binarySearch(components, Integer.valueOf(startBitOffset),
|
||||
bitOffsetComparator);
|
||||
if (startIndex < 0) {
|
||||
startIndex = -startIndex - 1;
|
||||
}
|
||||
|
@ -671,7 +699,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (offset >= structLength) {
|
||||
return;
|
||||
}
|
||||
int index = Collections.binarySearch(components, new Integer(offset), offsetComparator);
|
||||
int index = Collections.binarySearch(components, Integer.valueOf(offset), offsetComparator);
|
||||
|
||||
int offsetDelta = 0;
|
||||
int ordinalDelta = 0;
|
||||
|
@ -850,7 +878,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (index < 0 || index >= numComponents) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
int idx = Collections.binarySearch(components, Integer.valueOf(index), ordinalComparator);
|
||||
if (idx >= 0) {
|
||||
DataTypeComponent dtc = components.remove(idx);
|
||||
dtc.getDataType().removeParent(this);
|
||||
|
@ -1221,7 +1249,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
}
|
||||
}
|
||||
}
|
||||
int index = Collections.binarySearch(components, new Integer(ordinal), ordinalComparator);
|
||||
int index =
|
||||
Collections.binarySearch(components, Integer.valueOf(ordinal), ordinalComparator);
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
}
|
||||
|
@ -1256,7 +1285,7 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
if (index >= numComponents) {
|
||||
return 0;
|
||||
}
|
||||
int idx = Collections.binarySearch(components, new Integer(index), ordinalComparator);
|
||||
int idx = Collections.binarySearch(components, Integer.valueOf(index), ordinalComparator);
|
||||
DataTypeComponent dtc = null;
|
||||
if (idx < 0) {
|
||||
idx = -idx - 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue