mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
GP-4181 Corrected pointer stacking behavior for Data
This commit is contained in:
parent
ad7694a7a9
commit
2a7ac361e8
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user