GP-5861 - PDB, MDMang, and DTUtils optim - fix for processing of

truncated symbols and optional prefix on MDMang datatype demangling
This commit is contained in:
ghizard 2025-07-22 16:27:14 -04:00
parent 3cfa867ac3
commit 1684aaf61f
4 changed files with 91 additions and 58 deletions

View file

@ -20,6 +20,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import ghidra.app.util.SymbolPath; import ghidra.app.util.SymbolPath;
@ -211,6 +212,9 @@ public class MDMangUtils {
// When simple is true, we need to recurse the nested hierarchy to pull the names // When simple is true, we need to recurse the nested hierarchy to pull the names
// up to the main namespace level, so we set recurse = true // up to the main namespace level, so we set recurse = true
recurseNamespace(demangledParts, parsableItem, simple); recurseNamespace(demangledParts, parsableItem, simple);
if(ObjectUtils.isEmpty(regularPathName)) {
return createSymbolPath(demangledParts);
}
List<String> regularParts = SymbolPathParser.parse(regularPathName); List<String> regularParts = SymbolPathParser.parse(regularPathName);
int m = Integer.min(demangledParts.size(), regularParts.size()); int m = Integer.min(demangledParts.size(), regularParts.size());
@ -239,6 +243,10 @@ public class MDMangUtils {
parts.add(0, n); parts.add(0, n);
} }
return createSymbolPath(parts);
}
private static SymbolPath createSymbolPath(List<String> parts) {
SymbolPath sp = null; SymbolPath sp = null;
for (String part : parts) { for (String part : parts) {
sp = new SymbolPath(sp, part); sp = new SymbolPath(sp, part);

View file

@ -48,14 +48,13 @@ public class MDDataTypeParser {
throws MDException { throws MDException {
MDDataType dt = null; MDDataType dt = null;
if (dmang.peek() != '.') {
throw new MDException("MDMang: Mangled string is not that of a type.");
}
dmang.setProcessingMode(ProcessingMode.DEFAULT_STANDARD); dmang.setProcessingMode(ProcessingMode.DEFAULT_STANDARD);
try { try {
dmang.pushContext(); dmang.pushContext();
dmang.increment(); // skip the '.' if (dmang.peek() == '.') {
dmang.increment(); // skip the now-optional '.'
}
dt = parseDataType(dmang, isHighest); dt = parseDataType(dmang, isHighest);
dt.parse(); dt.parse();
dmang.popContext(); dmang.popContext();

View file

@ -104,13 +104,35 @@ public abstract class AbstractComplexTypeApplier extends MsDataTypeApplier {
// often had a member that also lambda that was marked with the exact same namespace/name // often had a member that also lambda that was marked with the exact same namespace/name
// as the containing structure. We found that the mangled names had more accurate and // as the containing structure. We found that the mangled names had more accurate and
// distinguished lambda numbers. // distinguished lambda numbers.
// Future: probably want to change both mangled and non-mangled symbols for best, as both
// could be truncated, but it is likely that partial results from a mangled symbol would
// have more detail than the partial results of a truncated non-mangled symbol. Thus,
// we should make getSymbolPathFromMangleTypeName() should do more work, even if the
// mangled symbol is truncated... perhaps we pass in a flag indicating to continue
// processing with the assumption that it is truncated?
boolean truncated = name.length() == 4096; // works unless real length was 4096
if (mangledName != null) { if (mangledName != null) {
symbolPath = getSymbolPathFromMangledTypeName(mangledName, name); symbolPath = getSymbolPathFromMangledTypeName(mangledName, truncated ? null : name);
} }
if (symbolPath == null) { if (symbolPath == null) {
symbolPath = symbolPath =
MDMangUtils.standarizeSymbolPathUnderscores( MDMangUtils.standarizeSymbolPathUnderscores(
new SymbolPath(SymbolPathParser.parse(name))); new SymbolPath(SymbolPathParser.parse(name)));
// If name was truncated at 4096 characters, then we likely do not have a complete
// symbol. In a rare case, we had a blank "name" because the truncation happened
// right after a namespace delimiter. Whether blank or not, we are appending
// a truncation message to the "name." Note, however, that we could have a rare case
// where there were exactly 4096 characters without truncation where we will still
// append the truncation message. We could try harder to ensure proper namespace
// parsing was done, and only then decide whether we need to add the message. That
// proper parsing is a separate research effort. For now, just append when we have
// 4096.
if (truncated) {
symbolPath =
new SymbolPath(symbolPath.getParent(), symbolPath.getName() + "_truncated");
}
} }
return symbolPath; return symbolPath;
} }

View file

@ -230,6 +230,10 @@ public class DataTypeUtilities {
if (isSameDataType(dataType1, dataType2)) { if (isSameDataType(dataType1, dataType2)) {
return true; return true;
} }
if (dataType2 instanceof DataTypeDB) {
// Leverage optimizations within most DataTypeDB implementations
return dataType2.isEquivalent(dataType1);
}
// otherwise, check if they are equivalent // otherwise, check if they are equivalent
return dataType1.isEquivalent(dataType2); return dataType1.isEquivalent(dataType2);
} }