mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 19:07:10 +08:00
GT-3000 tweak DWARF error reporting and dynamic size handling
This commit is contained in:
+32
-15
@@ -616,17 +616,26 @@ public class DWARFDataTypeImporter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String memberComment = null;
|
||||||
if (childDT.dataType instanceof Dynamic ||
|
if (childDT.dataType instanceof Dynamic ||
|
||||||
childDT.dataType instanceof FactoryDataType) {
|
childDT.dataType instanceof FactoryDataType) {
|
||||||
DWARFUtil.appendDescription(union, memberDesc("Missing member",
|
memberComment = "Unsupported dynamic size data type: " + childDT.dataType;
|
||||||
"dynamic length type", memberName, childDT, -1, bitSize, -1), "\n");
|
childDT.dataType = Undefined.getUndefinedDataType(1);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
int dtLen = childDT.dataType.getLength();
|
int dtLen = childDT.dataType.getLength();
|
||||||
if (unionSize != -1 && dtLen > unionSize) {
|
if (unionSize != -1 && dtLen > unionSize) {
|
||||||
DWARFUtil.appendDescription(union, memberDesc("Missing member",
|
if (dtLen > 1) {
|
||||||
"data type larger than union", memberName, childDT, -1, bitSize, -1), "\n");
|
// replace problematic datatype with 1 byte undefined placeholder
|
||||||
continue;
|
memberComment =
|
||||||
|
"Data type larger than union's declared size: " + childDT.dataType;
|
||||||
|
childDT.dataType = Undefined.getUndefinedDataType(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// can't do any fancy replacement, just add warning to union's description
|
||||||
|
DWARFUtil.appendDescription(union, memberDesc("Missing member",
|
||||||
|
"data type larger than union", memberName, childDT, -1, bitSize, -1), "\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBitField) {
|
if (isBitField) {
|
||||||
@@ -642,7 +651,7 @@ public class DWARFDataTypeImporter {
|
|||||||
// DWARF has attributes (DWARFAttribute.DW_AT_data_bit_offset, DWARFAttribute.DW_AT_bit_offset)
|
// DWARF has attributes (DWARFAttribute.DW_AT_data_bit_offset, DWARFAttribute.DW_AT_bit_offset)
|
||||||
// that specify the bit_offset of the field in the union. We don't use them.
|
// that specify the bit_offset of the field in the union. We don't use them.
|
||||||
try {
|
try {
|
||||||
union.addBitField(childDT.dataType, bitSize, memberName, null);
|
union.addBitField(childDT.dataType, bitSize, memberName, memberComment);
|
||||||
}
|
}
|
||||||
catch (InvalidDataTypeException e) {
|
catch (InvalidDataTypeException e) {
|
||||||
Msg.error(this,
|
Msg.error(this,
|
||||||
@@ -657,7 +666,7 @@ public class DWARFDataTypeImporter {
|
|||||||
// just a normal field
|
// just a normal field
|
||||||
try {
|
try {
|
||||||
DataTypeComponent dataTypeComponent =
|
DataTypeComponent dataTypeComponent =
|
||||||
union.add(childDT.dataType, memberName, null);
|
union.add(childDT.dataType, memberName, memberComment);
|
||||||
// adding a member to a composite can cause a clone() of the datatype instance, so
|
// adding a member to a composite can cause a clone() of the datatype instance, so
|
||||||
// update the instance mapping to keep track of the new instance.
|
// update the instance mapping to keep track of the new instance.
|
||||||
updateMapping(childDT.dataType, dataTypeComponent.getDataType());
|
updateMapping(childDT.dataType, dataTypeComponent.getDataType());
|
||||||
@@ -821,12 +830,8 @@ public class DWARFDataTypeImporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childDT.dataType instanceof Dynamic ||
|
boolean isDynamicSizedType = (childDT.dataType instanceof Dynamic ||
|
||||||
childDT.dataType instanceof FactoryDataType) {
|
childDT.dataType instanceof FactoryDataType);
|
||||||
DWARFUtil.appendDescription(structure, memberDesc("Missing member",
|
|
||||||
"dynamic length type", memberName, childDT, memberOffset, bitSize, -1), "\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (childDT.getPathName().equals(structure.getPathName()) && childDT != structure) {
|
//if (childDT.getPathName().equals(structure.getPathName()) && childDT != structure) {
|
||||||
// The child we are adding has the exact same fullpath as us.
|
// The child we are adding has the exact same fullpath as us.
|
||||||
@@ -858,6 +863,12 @@ public class DWARFDataTypeImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isBitField) {
|
if (isBitField) {
|
||||||
|
if (isDynamicSizedType) {
|
||||||
|
DWARFUtil.appendDescription(structure, memberDesc("Missing member",
|
||||||
|
"dynamic length type", memberName, childDT, memberOffset, bitSize, -1),
|
||||||
|
"\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!BitFieldDataType.isValidBaseDataType(childDT.dataType)) {
|
if (!BitFieldDataType.isValidBaseDataType(childDT.dataType)) {
|
||||||
DWARFUtil.appendDescription(structure,
|
DWARFUtil.appendDescription(structure,
|
||||||
memberDesc("Missing member",
|
memberDesc("Missing member",
|
||||||
@@ -920,6 +931,12 @@ public class DWARFDataTypeImporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
String memberComment = null;
|
||||||
|
if (isDynamicSizedType) {
|
||||||
|
memberComment = "Unsupported dynamic size data type: " + childDT.dataType;
|
||||||
|
childDT.dataType = Undefined.getUndefinedDataType(1);
|
||||||
|
}
|
||||||
|
|
||||||
int childLength = getUnpaddedDataTypeLength(childDT.dataType);
|
int childLength = getUnpaddedDataTypeLength(childDT.dataType);
|
||||||
if (memberOffset + childLength > structure.getLength()) {
|
if (memberOffset + childLength > structure.getLength()) {
|
||||||
DWARFUtil.appendDescription(structure, memberDesc("Missing member",
|
DWARFUtil.appendDescription(structure, memberDesc("Missing member",
|
||||||
@@ -941,7 +958,7 @@ public class DWARFDataTypeImporter {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
DataTypeComponent dtc = structure.replaceAtOffset(memberOffset,
|
DataTypeComponent dtc = structure.replaceAtOffset(memberOffset,
|
||||||
childDT.dataType, childLength, memberName, null);
|
childDT.dataType, childLength, memberName, memberComment);
|
||||||
|
|
||||||
// struct.replaceAtOffset() clones the childDT, which will mess up our
|
// struct.replaceAtOffset() clones the childDT, which will mess up our
|
||||||
// identity based mapping in currentImplDataTypeToDDT.
|
// identity based mapping in currentImplDataTypeToDDT.
|
||||||
|
|||||||
+17
-23
@@ -34,7 +34,6 @@ import ghidra.program.model.data.Enum;
|
|||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
|
||||||
import ghidra.program.model.pcode.Varnode;
|
import ghidra.program.model.pcode.Varnode;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
@@ -751,30 +750,26 @@ public class DWARFFunctionImporter {
|
|||||||
|
|
||||||
private Data createVariable(Address address, DataType dataType, DWARFNameInfo dni) {
|
private Data createVariable(Address address, DataType dataType, DWARFNameInfo dni) {
|
||||||
try {
|
try {
|
||||||
MemoryBlock block = currentProgram.getMemory().getBlock(address);
|
String eolComment = null;
|
||||||
if (dataType instanceof Dynamic || dataType instanceof FactoryDataType) {
|
if (dataType instanceof Dynamic || dataType instanceof FactoryDataType) {
|
||||||
if (!block.isInitialized()) {
|
eolComment = "Unsupported dynamic data type: " + dataType;
|
||||||
Msg.warn(this, "Dynamically sized data type in un-initialized memory: " +
|
dataType = Undefined.getUndefinedDataType(1);
|
||||||
dataType + " at " + address);
|
|
||||||
}
|
|
||||||
Data result = DataUtilities.createData(currentProgram, address, dataType, -1, false,
|
|
||||||
ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA);
|
|
||||||
variablesProcesesed.add(address);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
if (isDataTypeCompatibleWithExistingData(dataType, address)) {
|
if (!isDataTypeCompatibleWithExistingData(dataType, address)) {
|
||||||
Data result = DataUtilities.createData(currentProgram, address, dataType, -1, false,
|
appendComment(address, CodeUnit.EOL_COMMENT,
|
||||||
ClearDataMode.CLEAR_ALL_CONFLICT_DATA);
|
"Could not place DWARF static variable " +
|
||||||
variablesProcesesed.add(address);
|
dni.getNamespacePath().asFormattedString() + " : " + dataType +
|
||||||
return result;
|
" because existing data type conflicts.",
|
||||||
}
|
"\n");
|
||||||
else {
|
|
||||||
Msg.warn(this,
|
|
||||||
"Could not place static variable " +
|
|
||||||
dni.getNamespacePath().asFormattedString() + " : " + dataType + " at " +
|
|
||||||
address + " because existing data type conflicts.");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Data result = DataUtilities.createData(currentProgram, address, dataType, -1, false,
|
||||||
|
ClearDataMode.CLEAR_ALL_CONFLICT_DATA);
|
||||||
|
variablesProcesesed.add(address);
|
||||||
|
if (eolComment != null) {
|
||||||
|
appendComment(address, CodeUnit.EOL_COMMENT, eolComment, "\n");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch (CodeUnitInsertionException | DataTypeConflictException e) {
|
catch (CodeUnitInsertionException | DataTypeConflictException e) {
|
||||||
Msg.error(this, "Error creating data object at " + address, e);
|
Msg.error(this, "Error creating data object at " + address, e);
|
||||||
@@ -805,8 +800,7 @@ public class DWARFFunctionImporter {
|
|||||||
importSummary.globalVarsAdded++;
|
importSummary.globalVarsAdded++;
|
||||||
|
|
||||||
if (sourceInfo != null) {
|
if (sourceInfo != null) {
|
||||||
currentProgram.getListing().setComment(address, CodeUnit.EOL_COMMENT,
|
appendComment(address, CodeUnit.EOL_COMMENT, sourceInfo.getDescriptionStr(), "\n");
|
||||||
sourceInfo.getDescriptionStr());
|
|
||||||
|
|
||||||
if (varData != null) {
|
if (varData != null) {
|
||||||
moveIntoFragment(dni.getName(), varData.getMinAddress(), varData.getMaxAddress(),
|
moveIntoFragment(dni.getName(), varData.getMinAddress(), varData.getMaxAddress(),
|
||||||
|
|||||||
Reference in New Issue
Block a user