GP-1036 Improved RTTI handling of null pointer values. Changed IBO

pointers to return null for 0 value to retain backward compatibility.
Improved datatype drag onto root to preserve source category path.
This commit is contained in:
ghidra1 2022-03-15 10:59:16 -04:00
parent a02efe9c4c
commit 3acd14c48a
8 changed files with 66 additions and 40 deletions

View file

@ -15,8 +15,8 @@
*/
package ghidra.program.database.data;
import ghidra.program.model.address.AddressFactory;
import ghidra.program.model.address.AddressSpace;
import ghidra.docking.settings.Settings;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
/**
@ -60,12 +60,21 @@ public class PointerTypedefInspector {
if (!pointerTypeDef.isPointer()) {
return null;
}
Settings settings = pointerTypeDef.getDefaultSettings();
String spaceName =
AddressSpaceSettingsDefinition.DEF.getValue(pointerTypeDef.getDefaultSettings());
AddressSpaceSettingsDefinition.DEF.getValue(settings);
if (spaceName == null) {
return null;
}
return addrFactory.getAddressSpace(spaceName);
AddressSpace addressSpace = addrFactory.getAddressSpace(spaceName);
if (addressSpace instanceof SegmentedAddressSpace) {
// Other settings do not apply when SegmentedAddressSpace is used
// see PointerDataType.getAddressValue(MemBuffer, int, Settings)
return addressSpace;
}
// Address space setting ignored if Pointer Type has been specified
PointerType choice = PointerTypeSettingsDefinition.DEF.getType(settings);
return choice == PointerType.DEFAULT ? addressSpace : null;
}
/**

View file

@ -41,7 +41,9 @@ public class DataTypeMnemonicSettingsDefinition implements EnumSettingsDefinitio
/**
* Returns the format based on the specified settings
* @param settings the instance settings.
* @return the format value (HEX, DECIMAL, BINARY, OCTAL, CHAR)
* @return the mnemonic style (DEFAULT, ASSEMBLY, CSPEC).
* The ASSEMBLY style is returned if no setting has been made.
* The DEFAULT style corresponds to the use of {@link DataType#getName()}.
*/
public int getMnemonicStyle(Settings settings) {
if (settings == null) {

View file

@ -368,6 +368,7 @@ public class PointerDataType extends BuiltIn implements Pointer {
Program program = mem.getProgram();
String spaceName = AddressSpaceSettingsDefinition.DEF.getValue(settings);
if (spaceName != null) {
// this space may be ignored if pointer type specified
targetSpace = program.getAddressFactory().getAddressSpace(spaceName);
}
}
@ -377,12 +378,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
}
if (targetSpace instanceof SegmentedAddressSpace) {
// ignore other settings
// ignore other settings with SegmentedAddressSpace use
return getAddressValue(buf, size, targetSpace);
}
Long offset = getStoredOffset(buf, size);
if (offset == null) {
// Insufficient bytes
return null;
}
@ -403,7 +405,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
try {
PointerType choice = PointerTypeSettingsDefinition.DEF.getType(settings);
// Address space setting ignored if Pointer Type has been specified
if (choice == PointerType.IMAGE_BASE_RELATIVE && mem != null) {
if (addrOffset == 0) {
// Done for consistency with old ImageBaseOffsetDataType.
// A 0 relative offset is considerd invalid (NaP)
return null;
}
// must ignore AddressSpaceSettingsDefinition
Address imageBase = mem.getProgram().getImageBase();
targetSpace = imageBase.getAddressSpace();
@ -464,10 +472,16 @@ public class PointerDataType extends BuiltIn implements Pointer {
return null;
}
Long offset = getStoredOffset(buf, size);
if (offset == null) {
// Insufficient bytes
return null;
}
if (targetSpace instanceof SegmentedAddressSpace) {
try {
// NOTE: conversion assumes a little-endian space
return getSegmentedAddressValue(buf, size);
return getSegmentedAddressValue(buf, size, offset);
}
catch (AddressOutOfBoundsException e) {
// offset too large
@ -482,14 +496,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
return null;
}
Long offset = getStoredOffset(buf, size);
if (offset != null) {
try {
return targetSpace.getAddress(offset, true);
}
catch (AddressOutOfBoundsException e) {
// offset too large
}
try {
return targetSpace.getAddress(offset, true);
}
catch (AddressOutOfBoundsException e) {
// offset too large
}
return null;
}
@ -503,27 +516,20 @@ public class PointerDataType extends BuiltIn implements Pointer {
* @return address value returned as segmented Address object or null for
* unsupported pointer length or meory access error occurs.
*/
private static Address getSegmentedAddressValue(MemBuffer buf, int dataLen) {
private static Address getSegmentedAddressValue(MemBuffer buf, int dataLen, long storedOffset) {
SegmentedAddress a = (SegmentedAddress) buf.getAddress();
int segment = a.getSegment();
int offset = 0;
try {
switch (dataLen) {
case 2: // near pointer
offset = buf.getUnsignedShort(0);
break;
case 4: // far pointer
long value = buf.getUnsignedInt(0);
segment = (int) (value >> 16);
offset = (int) (value & 0xffff);
break;
default:
return null;
}
}
catch (MemoryAccessException e) {
return null;
int offset;
switch (dataLen) {
case 2: // near pointer
offset = (int) (storedOffset & 0xffff);
break;
case 4: // far pointer
segment = (int) ((storedOffset >> 16) & 0xffff);
offset = (int) (storedOffset & 0xffff);
break;
default:
return null;
}
SegmentedAddressSpace space = (SegmentedAddressSpace) a.getAddressSpace();
SegmentedAddress addr = space.getAddress(segment, offset);

View file

@ -43,7 +43,8 @@ public class PointerTypeSettingsDefinition
/**
* Returns the format based on the specified settings
* @param settings the instance settings or null for default value.
* @return the format value (HEX, DECIMAL, BINARY, OCTAL, CHAR)
* @return the {@link PointerType}. {@link PointerType#DEFAULT} will be returned
* if no setting has been made.
*/
public PointerType getType(Settings settings) {
if (settings == null) {