mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
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:
parent
a02efe9c4c
commit
3acd14c48a
8 changed files with 66 additions and 40 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue