GP-4181 Corrected pointer stacking behavior for Data

This commit is contained in:
ghidra1 2024-01-25 18:01:32 -05:00
parent ad7694a7a9
commit 2a7ac361e8

View File

@ -121,8 +121,7 @@ public final class DataUtilities {
!Undefined.isUndefined(dt))) {
return true;
}
if (clearMode == ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA &&
!isDefaultData(dt)) {
if (clearMode == ClearDataMode.CLEAR_ALL_DEFAULT_CONFLICT_DATA && !isDefaultData(dt)) {
return true;
}
return false;
@ -168,8 +167,22 @@ public final class DataUtilities {
if (!isParentData(data, addr)) {
existingLength = data.getLength();
if (data.isDefined() && newType.isEquivalent(existingType)) {
return data;
if (data.isDefined()) {
DataType existingDt = data.getDataType();
if (stackPointers && (newType instanceof Pointer) &&
(existingDt instanceof Pointer ptr)) {
if (isDefaultPointer(newType)) {
// When applying default-pointer to existing pointer replicate the outermost
// pointer type to wrap existing pointer (e.g., char* becomes char**)
newType = ptr.newPointer(ptr);
}
// Any use of stacking already reflected by newType
stackPointers = false;
}
if (newType.isEquivalent(existingType)) {
return data;
}
}
if (!stackPointers && isDataClearingDenied(existingType, clearMode)) {
@ -284,8 +297,7 @@ public final class DataUtilities {
return newType.equals(existingType);
}
private static void restoreReference(DataType newType, ReferenceManager refMgr,
Reference ref) {
private static void restoreReference(DataType newType, ReferenceManager refMgr, Reference ref) {
if (ref == null) {
return;
@ -309,11 +321,9 @@ public final class DataUtilities {
}
private static Reference getExternalPointerReference(Address addr, DataType newType,
boolean stackPointers,
ReferenceManager refMgr, DataType existingType) {
boolean stackPointers, ReferenceManager refMgr, DataType existingType) {
Reference extRef = null;
if ((stackPointers || newType instanceof Pointer) &&
existingType instanceof Pointer) {
if ((stackPointers || newType instanceof Pointer) && existingType instanceof Pointer) {
Reference[] refs = refMgr.getReferencesFrom(addr);
for (Reference ref : refs) {
if (ref.getOperandIndex() == 0 && ref.isExternalReference()) {
@ -358,8 +368,8 @@ public final class DataUtilities {
checkForDefinedData(dti, listing, newEnd, definedData.getMaxAddress(), clearMode);
}
else if (clearMode != ClearDataMode.CLEAR_ALL_CONFLICT_DATA) {
throw new CodeUnitInsertionException("Not enough space to create DataType " +
dti.getDataType().getDisplayName());
throw new CodeUnitInsertionException(
"Not enough space to create DataType " + dti.getDataType().getDisplayName());
}
listing.clearCodeUnits(addr, newEnd, false);
}
@ -370,14 +380,13 @@ public final class DataUtilities {
// ignore all defined data which may be cleared
while (end.compareTo(address) <= 0) {
Data definedData = listing.getDefinedDataAfter(end);
if (definedData == null ||
definedData.getMinAddress().compareTo(address) > 0) {
if (definedData == null || definedData.getMinAddress().compareTo(address) > 0) {
return;
}
if (isDataClearingDenied(definedData.getDataType(), clearMode)) {
throw new CodeUnitInsertionException("Not enough space to create DataType " +
dti.getDataType().getDisplayName());
throw new CodeUnitInsertionException(
"Not enough space to create DataType " + dti.getDataType().getDisplayName());
}
end = definedData.getMaxAddress();
}
@ -428,12 +437,14 @@ public final class DataUtilities {
}
DataType resultDt = newDataType;
if (stackPointers && isDefaultPointer(newDataType) &&
(originalDataType instanceof Pointer)) {
// wrap existing pointer with specified default pointer
resultDt = ((Pointer) newDataType).newPointer(originalDataType);
if (stackPointers && (newDataType instanceof Pointer) &&
(originalDataType instanceof Pointer ptr)) {
if (isDefaultPointer(newDataType)) {
// When applying default-pointer to existing pointer replicate the outermost
// pointer type to wrap existing pointer (e.g., char* becomes char**)
resultDt = ptr.newPointer(ptr);
}
}
else if (stackPointers && (originalDataType instanceof Pointer)) {
// replace existing pointer's base data type
resultDt = stackPointers((Pointer) originalDataType, newDataType);
@ -446,12 +457,11 @@ public final class DataUtilities {
}
private static boolean isDefaultPointer(DataType dt) {
if (!(dt instanceof Pointer)) {
return false;
if (dt instanceof Pointer ptr) {
DataType ptrDt = ptr.getDataType();
return ptrDt == null || ptrDt == DataType.DEFAULT;
}
Pointer p = (Pointer) dt;
DataType ptrDt = p.getDataType();
return ptrDt == null || ptrDt == DataType.DEFAULT;
return false;
}
/**