mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
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:
parent
3cfa867ac3
commit
1684aaf61f
4 changed files with 91 additions and 58 deletions
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue