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