mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-4181 Corrected pointer stacking behavior for Data
This commit is contained in:
parent
ad7694a7a9
commit
2a7ac361e8
1 changed files with 36 additions and 26 deletions
|
@ -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,8 +167,22 @@ public final class DataUtilities {
|
||||||
if (!isParentData(data, addr)) {
|
if (!isParentData(data, addr)) {
|
||||||
|
|
||||||
existingLength = data.getLength();
|
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)) {
|
if (!stackPointers && isDataClearingDenied(existingType, clearMode)) {
|
||||||
|
@ -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,12 +457,11 @@ 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();
|
||||||
|
return ptrDt == null || ptrDt == DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
Pointer p = (Pointer) dt;
|
return false;
|
||||||
DataType ptrDt = p.getDataType();
|
|
||||||
return ptrDt == null || ptrDt == DataType.DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue