Skip to content

Commit e5a3da2

Browse files
committed
GP-3726 do not use aligned-length for non-packed structures
1 parent 5d37d76 commit e5a3da2

21 files changed

+360
-266
lines changed

Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
*/
3131
public class CreateDataInStructureBackgroundCmd extends BackgroundCommand {
3232

33+
// TODO: Not sure any of this will work for a packed structure which does not support
34+
// offset-based component manipulation (see GP-3740)
35+
3336
private Address addr;
3437
private int length;
3538
private int[] startPath;
@@ -133,7 +136,7 @@ public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
133136
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
134137
// struct, struct.getComponent(index).getOffset());
135138
DataTypeInstance dti =
136-
DataTypeInstance.getDataTypeInstance(newDataType, length, true);
139+
DataTypeInstance.getDataTypeInstance(newDataType, length, false);
137140
if (dti == null || dti.getLength() > length) {
138141
break;
139142
}

Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
*/
2828
public class CreateDataInStructureCmd implements Command {
2929

30+
// TODO: Not sure any of this will work for a packed structure which does not support
31+
// offset-based component manipulation (see GP-3740)
32+
3033
private Address addr;
3134
private int[] componentPath;
3235
private DataType newDataType;
@@ -115,7 +118,7 @@ public boolean applyTo(DomainObject obj) {
115118
// MemBuffer memBuf = new ProgramStructureProviderContext(program,addr,
116119
// struct, dataComp.getParentOffset());
117120
DataTypeInstance dti =
118-
DataTypeInstance.getDataTypeInstance(newDataType, -1, true);
121+
DataTypeInstance.getDataTypeInstance(newDataType, -1, false);
119122
struct.replace(index, dti.getDataType(), dti.getLength());
120123
}
121124
}

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompEditorModel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,8 @@ public DataTypeComponent replace(DataType dataType) throws UsrException {
663663
* @throws UsrException if add fails
664664
*/
665665
public DataTypeComponent replace(int rowIndex, DataType dt) throws UsrException {
666-
DataTypeInstance dti = DataTypeHelper.getFixedLength(this, rowIndex, dt);
666+
DataTypeInstance dti =
667+
DataTypeHelper.getFixedLength(this, rowIndex, dt, usesAlignedLengthComponents());
667668
if (dti == null) {
668669
return null; // User cancelled from size dialog.
669670
}
@@ -1254,8 +1255,7 @@ public void validateComponentName(int rowIndex, String name) throws UsrException
12541255
}
12551256

12561257
@Override
1257-
public boolean setComponentName(int rowIndex, String name)
1258-
throws InvalidNameException {
1258+
public boolean setComponentName(int rowIndex, String name) throws InvalidNameException {
12591259

12601260
String oldName = getComponent(rowIndex).getFieldName();
12611261
if (Objects.equals(oldName, name)) {

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeEditorModel.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,8 @@ public void cycleDataType(CycleGroup cycleGroup) {
755755
int currentIndex = getMinIndexSelected();
756756
DataType dt = getNextCycleDataType(cycleGroup);
757757
if (dt != null) {
758-
DataTypeInstance dti = DataTypeHelper.getFixedLength(this, currentIndex, dt);
758+
DataTypeInstance dti = DataTypeHelper.getFixedLength(this, currentIndex, dt,
759+
usesAlignedLengthComponents());
759760
if (dti == null) {
760761
return;
761762
}
@@ -1162,7 +1163,7 @@ public DataTypeInstance validateComponentDataType(int rowIndex, String dtString)
11621163
dtName = dt.getDisplayName();
11631164
if (dtString.equals(dtName)) {
11641165
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
1165-
element.getLength(), true);
1166+
element.getLength(), usesAlignedLengthComponents());
11661167
}
11671168
}
11681169

@@ -1194,7 +1195,8 @@ public DataTypeInstance validateComponentDataType(int rowIndex, String dtString)
11941195
if (maxLength > 0 && newLength > maxLength) {
11951196
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
11961197
}
1197-
return DataTypeInstance.getDataTypeInstance(newDt, newLength, true);
1198+
return DataTypeInstance.getDataTypeInstance(newDt, newLength,
1199+
usesAlignedLengthComponents());
11981200
}
11991201

12001202
@SuppressWarnings("unused") // the exception is thrown by subclasses

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerModel.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ else if (columnIndex == getDataTypeColumn()) {
572572
DataType dt = dtc.getDataType();
573573
int dtLen = dt.getLength();
574574
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(),
575-
true);
575+
usesAlignedLengthComponents());
576576
}
577577
else if (columnIndex == getNameColumn()) {
578578
value = dtc.getFieldName();
@@ -1346,6 +1346,14 @@ protected long getCompositeID() {
13461346
return originalCompositeId;
13471347
}
13481348

1349+
/**
1350+
* Determine if {@link DataType#getAlignedLength() aligned-length} components should be used.
1351+
* @return true if aligned-length components should be used, else false
1352+
*/
1353+
protected boolean usesAlignedLengthComponents() {
1354+
return viewComposite.isPackingEnabled();
1355+
}
1356+
13491357
@Override
13501358
public void programArchitectureChanged(DataTypeManager dataTypeManager) {
13511359
// don't care

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/DataTypeHelper.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ else if (dt instanceof Dynamic && !((Dynamic) dt).canSpecifyLength()) {
146146
throw new InvalidDataTypeException(
147147
"Data type " + dt.getDisplayName() + " has no size and is not allowed.");
148148
}
149-
return DataTypeInstance.getDataTypeInstance(dt, dtLen, true);
149+
return DataTypeInstance.getDataTypeInstance(dt, dtLen,
150+
provider.editorModel.usesAlignedLengthComponents());
150151
}
151152

152153
public static int requestDtSize(CompositeEditorProvider provider, String dtName,
@@ -177,12 +178,14 @@ public static int requestDtSize(CompositeEditorProvider provider, String dtName,
177178
*
178179
* @param index the component index of where to add the data type.
179180
* @param dt the data type to add
180-
*
181+
* @param useAlignedLength if true a fixed-length primitive data type will use its
182+
* {@link DataType#getAlignedLength() aligned-length}, otherwise it will use its
183+
* {@link DataType#getLength() raw length}.
181184
* @return the data type and its size or null if the user canceled when
182185
* prompted for a size.
183186
*/
184187
public static DataTypeInstance getFixedLength(CompositeEditorModel model, int index,
185-
DataType dt) {
188+
DataType dt, boolean useAlignedLength) {
186189
if (dt instanceof FactoryDataType) {
187190
model.setStatus("Factory data types are not allowed in a composite data type.");
188191
return null;
@@ -203,7 +206,7 @@ public static DataTypeInstance getFixedLength(CompositeEditorModel model, int in
203206
int maxBytes = model.getMaxReplaceLength(index);
204207
return requestBytes(model, dt, maxBytes);
205208
}
206-
return DataTypeInstance.getDataTypeInstance(dt, length, true);
209+
return DataTypeInstance.getDataTypeInstance(dt, length, useAlignedLength);
207210
}
208211

209212
public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType dt,
@@ -228,7 +231,8 @@ public static DataTypeInstance requestBytes(CompositeEditorModel model, DataType
228231

229232
if (size >= 1) {
230233
model.setLastNumBytes(size);
231-
return DataTypeInstance.getDataTypeInstance(dt, size, true);
234+
return DataTypeInstance.getDataTypeInstance(dt, size,
235+
model.usesAlignedLengthComponents());
232236
}
233237
return null;
234238
}

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/StructureEditorModel.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ else if (columnIndex == getDataTypeColumn()) {
162162
DataType dt = dtc.getDataType();
163163
int dtLen = dt.getLength();
164164
return DataTypeInstance.getDataTypeInstance(dt, (dtLen > 0) ? dtLen : dtc.getLength(),
165-
true);
165+
usesAlignedLengthComponents());
166166
}
167167
else if (columnIndex == getNameColumn()) {
168168
value = dtc.getFieldName();
@@ -1154,8 +1154,7 @@ void createInternalStructure() throws UsrException {
11541154
}
11551155

11561156
private void doCreateInternalStructure(DataTypeManager dtm, CategoryPath categoryPath,
1157-
String name, TaskMonitor monitor)
1158-
throws InvalidDataTypeException, UsrException {
1157+
String name, TaskMonitor monitor) throws InvalidDataTypeException, UsrException {
11591158

11601159
int length = 0;
11611160
StructureDataType structureDataType =
@@ -1250,9 +1249,8 @@ private String showNameDialog(final String defaultName, final CategoryPath catPa
12501249
};
12511250

12521251
String title = "Specify the Structure's Name";
1253-
InputDialog nameStructureDialog =
1254-
new InputDialog(title, new String[] { "New Structure's Name: " },
1255-
new String[] { defaultName }, listener);
1252+
InputDialog nameStructureDialog = new InputDialog(title,
1253+
new String[] { "New Structure's Name: " }, new String[] { defaultName }, listener);
12561254

12571255
provider.getPlugin().getTool().showDialog(nameStructureDialog);
12581256

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/CreateArrayAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ private void createArrayInStructure(Program program, InteriorSelection sel) {
141141
}
142142

143143
int length = sel.getByteLength();
144+
// Arrays currently use aligned-length only
144145
int numElements = length / dt.getAlignedLength();
145146

146147
Command cmd = new CreateArrayInStructureCmd(from.getAddress(), numElements, dt,
@@ -161,6 +162,7 @@ private int getMaxNoConflictElements(Structure struct, int index, DataType dt) {
161162
}
162163
length += dtc.getLength();
163164
}
165+
// Arrays currently use aligned-length only
164166
return length / dt.getAlignedLength();
165167
}
166168

@@ -171,6 +173,7 @@ private int getMaxElements(Structure struct, int index, DataType dt) {
171173
DataTypeComponent dtc = struct.getComponent(index++);
172174
length += dtc.getLength();
173175
}
176+
// Arrays currently use aligned-length only
174177
return length / dt.getAlignedLength();
175178
}
176179

Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/stackeditor/StackEditorModel.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public Object getValueAt(int rowIndex, int columnIndex) {
203203
dt = element.getDataType();
204204
dtLen = dt.getLength();
205205
return DataTypeInstance.getDataTypeInstance(dt,
206-
(dtLen > 0) ? dtLen : element.getLength(), true);
206+
(dtLen > 0) ? dtLen : element.getLength(), usesAlignedLengthComponents());
207207
case NAME:
208208
String fieldName = getFieldNameAtRow(rowIndex, (StackFrameDataType) viewComposite);
209209
if (fieldName == null) {
@@ -813,8 +813,7 @@ public void validateComponentName(int currentIndex, String name) throws UsrExcep
813813
}
814814

815815
@Override
816-
public boolean setComponentName(int rowIndex, String newName)
817-
throws InvalidNameException {
816+
public boolean setComponentName(int rowIndex, String newName) throws InvalidNameException {
818817

819818
if (newName.trim().length() == 0) {
820819
newName = null;
@@ -1125,8 +1124,9 @@ public DataTypeComponent replace(int index, DataType dt, int dtLength) throws Us
11251124
OffsetPairs offsetSelection = getRelOffsetSelection();
11261125
int transID = startTransaction("Apply Data Type \"" + dt.getName() + "\"");
11271126
try {
1128-
fieldEdited(DataTypeInstance.getDataTypeInstance(dt, dtLength, true), index,
1129-
getDataTypeColumn());
1127+
fieldEdited(
1128+
DataTypeInstance.getDataTypeInstance(dt, dtLength, usesAlignedLengthComponents()),
1129+
index, getDataTypeColumn());
11301130
setRelOffsetSelection(offsetSelection);
11311131
}
11321132
finally {
@@ -1155,6 +1155,7 @@ public int getMaxElements() {
11551155
if (max == Integer.MAX_VALUE) {
11561156
return Integer.MAX_VALUE;
11571157
}
1158+
// Arrays currently use aligned-length only
11581159
return max / dtc.getDataType().getAlignedLength();
11591160
}
11601161

@@ -1318,7 +1319,7 @@ public DataTypeInstance validateComponentDataType(int index, String dtString)
13181319
dtName = dt.getDisplayName();
13191320
if (dtString.equals(dtName)) {
13201321
return DataTypeInstance.getDataTypeInstance(element.getDataType(),
1321-
element.getLength(), true);
1322+
element.getLength(), usesAlignedLengthComponents());
13221323
}
13231324
}
13241325

@@ -1344,7 +1345,8 @@ public DataTypeInstance validateComponentDataType(int index, String dtString)
13441345
if (maxLength > 0 && newLength > maxLength) {
13451346
throw new UsrException(newDt.getDisplayName() + " doesn't fit.");
13461347
}
1347-
return DataTypeInstance.getDataTypeInstance(newDt, newLength, true);
1348+
return DataTypeInstance.getDataTypeInstance(newDt, newLength,
1349+
usesAlignedLengthComponents());
13481350
}
13491351

13501352
@Override

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramProviderContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public DataTypeComponent getDataTypeComponent(int offset) {
5858

5959
DataType dt = data.getDataType();
6060
int length = DataTypeComponentImpl.getPreferredComponentLength(dt,
61-
Math.max(data.getLength(), dt.getAlignedLength()));
61+
Math.max(data.getLength(), dt.getLength()));
6262
String label = null;
6363
Symbol symbol = data.getPrimarySymbol();
6464
if (symbol != null && !symbol.isDynamic()) {

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/core/data/ProgramStructureProviderContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
*/
1616
package ghidra.app.plugin.core.data;
1717

18+
import java.util.ArrayList;
19+
1820
import ghidra.program.model.address.Address;
1921
import ghidra.program.model.data.*;
2022
import ghidra.program.model.lang.DataTypeProviderContext;
2123
import ghidra.program.model.listing.Data;
2224
import ghidra.program.model.listing.Program;
2325
import ghidra.program.util.ProgramLocation;
2426

25-
import java.util.ArrayList;
26-
2727
public class ProgramStructureProviderContext implements DataTypeProviderContext {
2828
Program program;
2929
Address addr;

0 commit comments

Comments
 (0)