mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GT-3347 - code review tweaks
Handle bitfields formatted as char. Change how endianness affects display of char sequences in data elements.
This commit is contained in:
parent
73155ce499
commit
603ca28c01
4 changed files with 28 additions and 21 deletions
|
@ -20,7 +20,6 @@ import ghidra.program.model.data.ByteDataType;
|
||||||
import ghidra.program.model.data.StringDataInstance;
|
import ghidra.program.model.data.StringDataInstance;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import utilities.util.ArrayUtilities;
|
|
||||||
|
|
||||||
public class ConvertToCharAction extends AbstractConvertAction {
|
public class ConvertToCharAction extends AbstractConvertAction {
|
||||||
public static final String ACTION_NAME = "Convert To Char";
|
public static final String ACTION_NAME = "Convert To Char";
|
||||||
|
@ -49,10 +48,6 @@ public class ConvertToCharAction extends AbstractConvertAction {
|
||||||
@Override
|
@Override
|
||||||
protected String convertToString(Program program, Scalar scalar, boolean isData) {
|
protected String convertToString(Program program, Scalar scalar, boolean isData) {
|
||||||
byte[] bytes = scalar.byteArrayValue();
|
byte[] bytes = scalar.byteArrayValue();
|
||||||
boolean isLE = !program.getMemory().isBigEndian();
|
|
||||||
if (isLE) {
|
|
||||||
bytes = ArrayUtilities.reverse(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return StringDataInstance.getCharRepresentation(ByteDataType.dataType, bytes, null);
|
return StringDataInstance.getCharRepresentation(ByteDataType.dataType, bytes, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import ghidra.docking.settings.*;
|
||||||
import ghidra.program.model.mem.MemBuffer;
|
import ghidra.program.model.mem.MemBuffer;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import ghidra.util.StringFormat;
|
import ghidra.util.StringFormat;
|
||||||
|
import utilities.util.ArrayUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base type for integer data types such as {@link CharDataType chars}, {@link IntegerDataType ints},
|
* Base type for integer data types such as {@link CharDataType chars}, {@link IntegerDataType ints},
|
||||||
|
@ -224,32 +225,29 @@ public abstract class AbstractIntegerDataType extends BuiltIn implements ArraySt
|
||||||
return "??";
|
return "??";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isLE = !ENDIAN.isBigEndian(settings, buf);
|
||||||
|
if (isLE) {
|
||||||
|
bytes = ArrayUtilities.reverse(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) {
|
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) {
|
||||||
return StringDataInstance.getCharRepresentation(this, bytes, settings);
|
return StringDataInstance.getCharRepresentation(this, bytes, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isBigEndian = ENDIAN.isBigEndian(settings, buf);
|
|
||||||
|
|
||||||
if (!isBigEndian) {
|
|
||||||
byte[] flipped = new byte[size];
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
flipped[i] = bytes[size - i - 1];
|
|
||||||
}
|
|
||||||
bytes = flipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return getRepresentation(new BigInteger(bytes), settings, 8 * length);
|
return getRepresentation(new BigInteger(bytes), settings, 8 * length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get integer representation of the big-endian value.
|
* Get integer representation of the big-endian value.
|
||||||
|
* <p>
|
||||||
|
* Does not handle CHAR format, use {@link StringDataInstance#getCharRepresentation(DataType, byte[], Settings)}
|
||||||
|
*
|
||||||
* @param bigInt BigInteger value with the appropriate sign
|
* @param bigInt BigInteger value with the appropriate sign
|
||||||
* @param settings integer format settings (PADDING, FORMAT, etc.)
|
* @param settings integer format settings (PADDING, FORMAT, etc.)
|
||||||
* @param bitLength number of value bits to be used from bigInt
|
* @param bitLength number of value bits to be used from bigInt
|
||||||
* @return formatted integer string
|
* @return formatted integer string
|
||||||
*/
|
*/
|
||||||
public String getRepresentation(BigInteger bigInt, Settings settings, int bitLength) {
|
/*package*/ String getRepresentation(BigInteger bigInt, Settings settings, int bitLength) {
|
||||||
|
|
||||||
int format = getFormatSettingsDefinition().getFormat(settings);
|
int format = getFormatSettingsDefinition().getFormat(settings);
|
||||||
boolean padded = PADDING.isPadded(settings);
|
boolean padded = PADDING.isPadded(settings);
|
||||||
|
|
|
@ -17,11 +17,12 @@ package ghidra.program.model.data;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import ghidra.docking.settings.Settings;
|
import ghidra.docking.settings.*;
|
||||||
import ghidra.docking.settings.SettingsDefinition;
|
|
||||||
import ghidra.program.model.mem.MemBuffer;
|
import ghidra.program.model.mem.MemBuffer;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
|
import ghidra.util.DataConverter;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
import utilities.util.ArrayUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>BitFieldDataType</code> provides a means of defining a minimally sized bit-field
|
* <code>BitFieldDataType</code> provides a means of defining a minimally sized bit-field
|
||||||
|
@ -406,7 +407,20 @@ public class BitFieldDataType extends AbstractDataType {
|
||||||
if (dt instanceof Enum) {
|
if (dt instanceof Enum) {
|
||||||
return ((Enum) dt).getRepresentation(big, settings, effectiveBitSize);
|
return ((Enum) dt).getRepresentation(big, settings, effectiveBitSize);
|
||||||
}
|
}
|
||||||
return ((AbstractIntegerDataType) dt).getRepresentation(big, settings, effectiveBitSize);
|
AbstractIntegerDataType intDT = (AbstractIntegerDataType) dt;
|
||||||
|
if (intDT.getFormatSettingsDefinition().getFormat(
|
||||||
|
settings) == FormatSettingsDefinition.CHAR) {
|
||||||
|
int bytesLen = BitFieldDataType.getMinimumStorageSize(bitSize);
|
||||||
|
byte[] bytes = DataConverter.getInstance(getDataOrganization().isBigEndian()).getBytes(
|
||||||
|
big, bytesLen);
|
||||||
|
if (!EndianSettingsDefinition.ENDIAN.isBigEndian(settings, buf)) {
|
||||||
|
bytes = ArrayUtilities.reverse(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringDataInstance.getCharRepresentation(this, bytes, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return intDT.getRepresentation(big, settings, effectiveBitSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -283,7 +283,7 @@ public class StringDataInstance {
|
||||||
if (dataType instanceof AbstractStringDataType) {
|
if (dataType instanceof AbstractStringDataType) {
|
||||||
return ((AbstractStringDataType) dataType).getStringLayout();
|
return ((AbstractStringDataType) dataType).getStringLayout();
|
||||||
}
|
}
|
||||||
if (dataType instanceof AbstractIntegerDataType) {
|
if (dataType instanceof AbstractIntegerDataType || dataType instanceof BitFieldDataType) {
|
||||||
return StringLayoutEnum.FIXED_LEN;
|
return StringLayoutEnum.FIXED_LEN;
|
||||||
}
|
}
|
||||||
return StringLayoutEnum.NULL_TERMINATED_BOUNDED;
|
return StringLayoutEnum.NULL_TERMINATED_BOUNDED;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue