Skip to content

Instantly share code, notes, and snippets.

@agatti
Created May 13, 2020 08:29
Show Gist options
  • Save agatti/150f1db354c2503280ffe25462e5f6f7 to your computer and use it in GitHub Desktop.
Save agatti/150f1db354c2503280ffe25462e5f6f7 to your computer and use it in GitHub Desktop.
CP1600 SBIDECLE data type Raw
package ghidra.program.model.data;
import java.math.BigInteger;
import ghidra.docking.settings.FormatSettingsDefinition;
import ghidra.docking.settings.Settings;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.scalar.Scalar;
public class SignedBiDecleDataType extends AbstractIntegerDataType {
public final static SignedBiDecleDataType dataType = new SignedBiDecleDataType();
public SignedBiDecleDataType() {
this(null);
}
public SignedBiDecleDataType(DataTypeManager dtm) {
super("sbidecle", true, dtm);
}
@Override
public int getLength() {
return getDataOrganization().getIntegerSize();
}
@Override
public boolean isDynamicallySized() {
return true;
}
@Override
public String getDescription() {
return "Signed 16-bit data type spread over two words";
}
@Override
public String getCDeclaration() {
return C_SIGNED_SHORT;
}
private Object getScalar(MemBuffer buf, Settings settings, int length) {
Object value = super.getValue(buf, settings, length);
long truncated;
if (value instanceof BigInteger) {
truncated = ((BigInteger) value).intValue() & 0x00FF00FF;
} else if (value instanceof Scalar) {
truncated = (int) ((Scalar) value).getValue() & 0x00FF00FF;
} else {
return value;
}
if (ENDIAN.isBigEndian(settings, buf)) {
truncated = ((truncated & 0x00FF0000) >> 16) | ((truncated & 0x000000FF) << 8);
} else {
truncated = ((truncated & 0x00FF0000) >> 8) | (truncated & 0x000000FF);
}
long abs = Math.abs(truncated) & 0x7FFF;
return new Scalar(getLength() * 8, ((truncated & 0x8000) == 0x8000) ? -abs : abs,
(truncated & 0x8000) == 0x8000);
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
return getScalar(buf, settings, length);
}
@Override
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
Object possibleScalar = getScalar(buf, settings, length);
if (possibleScalar instanceof Scalar) {
Scalar scalar = (Scalar) possibleScalar;
byte[] buffer = new byte[2];
if (ENDIAN.isBigEndian(settings, buf)) {
buffer[0] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8);
buffer[1] = (byte) (scalar.getUnsignedValue() & 0x00FF);
} else {
buffer[0] = (byte) (scalar.getUnsignedValue() & 0x00FF);
buffer[1] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8);
}
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) {
return StringDataInstance.getCharRepresentation(this, buffer, settings);
}
// Truncate to two bytes as it is still a word underneath...
return super.getRepresentation(new BigInteger(buffer), settings, 16);
}
return super.getRepresentation(buf, settings, length);
}
@Override
public AbstractIntegerDataType getOppositeSignednessDataType() {
return BiDecleDataType.dataType.clone(getDataTypeManager());
}
@Override
public SignedBiDecleDataType clone(DataTypeManager dtm) {
if (dtm == getDataTypeManager()) {
return this;
}
return new SignedBiDecleDataType(dtm);
}
@Override
public String getCTypeDeclaration(DataOrganization dataOrganization) {
return "short";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment