GP-1827 - Fix NPE for null PDB DBI; static symbol/type parsing methods help remedy

This commit is contained in:
ghizard 2022-04-13 15:26:10 -04:00
parent 07a9878b94
commit d86b60e6b2
19 changed files with 655 additions and 537 deletions

View File

@ -122,8 +122,8 @@ public class PdbQuery {
TaskMonitor monitor = script.getMonitor();
monitor.initialize(num);
println(script, "Searching " + num + " PDB data type components...");
for (int indexNumber =
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
.getTypeIndexMaxExclusive(); indexNumber++) {
monitor.checkCanceled();
RecordNumber recordNumber = RecordNumber.typeRecordNumber(indexNumber);
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
@ -161,8 +161,8 @@ public class PdbQuery {
TaskMonitor monitor = script.getMonitor();
monitor.initialize(num);
println(script, "Searching " + num + " PDB item type components...");
for (int indexNumber =
ipi.getTypeIndexMin(); indexNumber < ipi.getTypeIndexMaxExclusive(); indexNumber++) {
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
.getTypeIndexMaxExclusive(); indexNumber++) {
monitor.checkCanceled();
RecordNumber recordNumber = RecordNumber.itemRecordNumber(indexNumber);
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
@ -188,17 +188,21 @@ public class PdbQuery {
public static void searchSymbols(GhidraScript script, AbstractPdb pdb, String searchString)
throws CancelledException {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
StringBuilder results = new StringBuilder();
results.append('\n');
int numModules = pdb.getDebugInfo().getNumModules();
int numModules = debugInfo.getNumModules();
TaskMonitor monitor = script.getMonitor();
int numSymbols = 0;
for (int module = 0; module <= numModules; module++) {
monitor.checkCanceled();
try {
Map<Long, AbstractMsSymbol> symbols =
pdb.getDebugInfo().getModuleSymbolsByOffset(module);
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(module);
numSymbols += symbols.size();
}
catch (PdbException e) {
@ -211,8 +215,7 @@ public class PdbQuery {
for (int module = 0; module <= numModules; module++) {
monitor.checkCanceled();
try {
Map<Long, AbstractMsSymbol> symbols =
pdb.getDebugInfo().getModuleSymbolsByOffset(module);
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(module);
numSymbols += symbols.size();
for (Map.Entry<Long, AbstractMsSymbol> entry : symbols.entrySet()) {
monitor.checkCanceled();

View File

@ -86,9 +86,6 @@ public abstract class AbstractPdb implements AutoCloseable {
protected boolean substreamsDeserialized = false;
//==============================================================================================
private TypeParser typeParser;
private SymbolParser symbolParser;
//==============================================================================================
// Ghidra-specific:
private PdbReaderMetrics pdbReaderMetrics = new PdbReaderMetrics(this);
@ -141,7 +138,7 @@ public abstract class AbstractPdb implements AutoCloseable {
}
/**
* Returns the main {@link PdbIdentifiers} found in the PDB Directory.
* Returns the main {@link PdbIdentifiers} found in the PDB Directory.
* @return {@link PdbIdentifiers} of information.
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
* inability to read required bytes.
@ -151,7 +148,7 @@ public abstract class AbstractPdb implements AutoCloseable {
parseDBI();
if (debugInfo != null) {
try {
// dbiAge and targetProcessor set during deserialization of new DBI header
// dbiAge and targetProcessor set during deserialization of new DBI header
debugInfo.deserialize(true, TaskMonitor.DUMMY);
}
catch (CancelledException e) {
@ -198,22 +195,6 @@ public abstract class AbstractPdb implements AutoCloseable {
PdbLog.message(pdbReaderMetrics::getPostProcessingReport);
}
/**
* Returns the {@link TypeParser} created for this PDB.
* @return {@link TypeParser} for this PDB.
*/
public TypeParser getTypeParser() {
return typeParser;
}
/**
* Returns the {@link SymbolParser} created for this PDB.
* @return {@link SymbolParser} for this PDB.
*/
public SymbolParser getSymbolParser() {
return symbolParser;
}
/**
* Returns the Version Number of the PDB.
* @return Version Number of the PDB.
@ -281,7 +262,7 @@ public abstract class AbstractPdb implements AutoCloseable {
// TODO: this method should be package protected
public void setTargetProcessor(Processor targetProcessorIn) {
/**
* Should we allow an overwrite? The {@link PdbNewDebugInfo} value (mapped from
* Should we allow an overwrite? The {@link PdbNewDebugInfo} value (mapped from
* {@link ImageFileMachine}) should be processed and laid down first. Subsequent values
* can come from {@link AbstractCompile2MsSymbol} and {@link Compile3MsSymbol}. Note:
* {@link PdbDebugInfo} does not carry {@link ImageFileMachine}, and thus no mapping
@ -312,7 +293,7 @@ public abstract class AbstractPdb implements AutoCloseable {
/**
* Returns the ItemProgramInterface (of type {@link AbstractTypeProgramInterface})
* component.
* @return ItemProgramInterface (of type {@link AbstractTypeProgramInterface}) component
* @return ItemProgramInterface (of type {@link AbstractTypeProgramInterface}) component
* or null if not available.
*/
public AbstractTypeProgramInterface getItemProgramInterface() {
@ -327,14 +308,6 @@ public abstract class AbstractPdb implements AutoCloseable {
return debugInfo;
}
/**
* Returns the {@link SymbolRecords} component of the PDB.
* @return {@link SymbolRecords} component.
*/
public SymbolRecords getSymbolRecords() {
return debugInfo.getSymbolRecords();
}
/**
* Returns the record for the associated record number, which is expected to match the
* desired class
@ -441,7 +414,7 @@ public abstract class AbstractPdb implements AutoCloseable {
* @param monitor {@link TaskMonitor} used for checking cancellation.
* @return Version number.
* @throws IOException on file I/O issues.
* @throws PdbException on parsing issues.
* @throws PdbException on parsing issues.
* @throws CancelledException Upon user cancellation.
*/
static int deserializeVersionNumber(AbstractMsf msf, TaskMonitor monitor)
@ -469,14 +442,11 @@ public abstract class AbstractPdb implements AutoCloseable {
strings = new ArrayList<>();
parameters = new ArrayList<>();
nameTable = new NameTable(this);
typeParser = new TypeParser(this);
symbolParser = new SymbolParser(this);
}
/**
* Deserializes the main {@link PdbIdentifiers} found in the PDB Directory from the
* {@link PdbByteReader}.
* {@link PdbByteReader}.
* @param monitor {@link TaskMonitor} used for checking cancellation.
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
* inability to read required bytes.
@ -494,7 +464,7 @@ public abstract class AbstractPdb implements AutoCloseable {
return msf;
}
//TODO Not sure if we will keep this method or if more gets added to it.
//TODO Not sure if we will keep this method or if more gets added to it.
/**
* Deserializes the sub-streams for this {@link AbstractPdb} object.
* @param monitor {@link TaskMonitor} used for checking cancellation.

View File

@ -168,7 +168,11 @@ public abstract class AbstractSymbolInformation {
protected void generateSymbolsList(TaskMonitor monitor)
throws PdbException, CancelledException {
symbols = new ArrayList<>();
Map<Long, AbstractMsSymbol> symbolsByOffset = pdb.getDebugInfo().getSymbolsByOffset();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
Map<Long, AbstractMsSymbol> symbolsByOffset = debugInfo.getSymbolsByOffset();
for (SymbolHashRecord record : hashRecords) {
monitor.checkCanceled();
long offset = record.getOffset() - 2; // Modified offset
@ -353,7 +357,7 @@ public abstract class AbstractSymbolInformation {
}
/**
*
*
* @param reader {@link PdbByteReader} containing the data buffer to process.
* @param monitor {@link TaskMonitor} used for checking cancellation.
* @throws PdbException Upon not enough data left to parse.

View File

@ -265,7 +265,6 @@ public abstract class AbstractTypeProgramInterface implements TPI {
throws PdbException, CancelledException {
int recordLength;
int recordNumber = typeIndexMin;
TypeParser parser = pdb.getTypeParser();
while (reader.hasMore()) {
monitor.checkCanceled();
@ -279,8 +278,8 @@ public abstract class AbstractTypeProgramInterface implements TPI {
// know which of the two to call, and we'd have to create an AbstractTypeIndex:
// parseTypeRecordNumber(recordReader, recordNumber);
// parseItemRecordNumber(recordReader, recordNumber);
AbstractMsType type =
parser.parseRecord(recordReader, RecordNumber.make(recordCategory, recordNumber));
AbstractMsType type = TypeParser.parseRecord(pdb, recordReader,
RecordNumber.make(recordCategory, recordNumber));
typeList.add(type);
recordNumber++;
}
@ -392,7 +391,7 @@ public abstract class AbstractTypeProgramInterface implements TPI {
throws IOException, PdbException, CancelledException {
// I don't believe we need to parse and process the hash table. They seemingly are
// used to point from a TypeIndex to a raw (byte[]) Type Record. We are not
// currently maintaining our records in this raw form; we are processing (parsing)
// currently maintaining our records in this raw form; we are processing (parsing)
// them as we read each record buffer.
// Note that we have no evidence of how the Auxiliary stream is used. Its
// contents might need to get concatenated with the contents of the primary

View File

@ -137,7 +137,7 @@ public class DebugData {
* each particular debug type (e.g., the first stream number read is for the stream containing
* Frame Pointer Omission debug data). A stream number of 0XFFFF says that there is no data
* for that debug type; else the stream number represents the stream that should
* be deserialized to retrieve the debug data of that type. The
* be deserialized to retrieve the debug data of that type. The
* {@link #deserialize(TaskMonitor)} method deserializes each of these streams
* that are valid to the corresponding debug data type.
* @param reader {@link PdbByteReader} from which to parse the header.
@ -323,9 +323,10 @@ public class DebugData {
// }
// TODO: More work possible. See XData processing and notes there. This is very
// incomplete.
if (pdb.getDebugInfo() instanceof PdbNewDebugInfo) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo instanceof PdbNewDebugInfo) {
//Processor target = pdb.getTargetProcessor();
PdbNewDebugInfo dbi = (PdbNewDebugInfo) pdb.getDebugInfo();
PdbNewDebugInfo dbi = (PdbNewDebugInfo) debugInfo;
ImageFileMachine machine = dbi.getMachineType();
switch (machine) {
case IA64:

View File

@ -877,8 +877,12 @@ public class PdbReaderMetrics {
}
public void witnessedSectionSegmentNumber(int segment) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
if (numSegments == -1) {
numSegments = pdb.getDebugInfo().getSegmentMapList().size();
numSegments = debugInfo.getSegmentMapList().size();
}
if (segment < 0 || segment > numSegments) {
PdbLog.message("segment " + segment + " out of range [0," + numSegments + ")");

View File

@ -26,35 +26,30 @@ import ghidra.util.exception.CancelledException;
*/
public class SymbolParser {
//==============================================================================================
// Internals
//==============================================================================================
private AbstractPdb pdb;
//==============================================================================================
// API
//==============================================================================================
/**
* Constructor.
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
*/
public SymbolParser(AbstractPdb pdb) {
Objects.requireNonNull(pdb, "pdb cannot be null");
this.pdb = pdb;
private SymbolParser() {
}
/**
* Deserializes an {@link AbstractMsSymbol} from the {@link PdbByteReader} and returns it.
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the symbol record.
* @return {@link AbstractMsSymbol} that was parsed.
* @throws PdbException upon error parsing a field.
* @throws CancelledException Upon user cancellation.
*/
public AbstractMsSymbol parse(PdbByteReader reader) throws PdbException, CancelledException {
public static AbstractMsSymbol parse(AbstractPdb pdb, PdbByteReader reader)
throws PdbException, CancelledException {
Objects.requireNonNull(pdb, "pdb cannot be null");
int symbolTypeId = reader.parseUnsignedShortVal();
AbstractMsSymbol symbol;
try {
symbol = parseRecord(symbolTypeId, reader);
symbol = parseRecord(pdb, symbolTypeId, reader);
}
catch (PdbException e) {
symbol = new BadMsSymbol(pdb, symbolTypeId);
@ -64,14 +59,15 @@ public class SymbolParser {
/**
* Deserializes an {@link AbstractMsSymbol} from the {@link PdbByteReader} and returns it.
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
* @param symbolTypeId the PDB ID for the symbol type to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the symbol record.
* @return {@link AbstractMsSymbol} that was parsed.
* @throws PdbException upon error parsing a field.
* @throws CancelledException Upon user cancellation.
*/
private AbstractMsSymbol parseRecord(int symbolTypeId, PdbByteReader reader)
throws PdbException, CancelledException {
private static AbstractMsSymbol parseRecord(AbstractPdb pdb, int symbolTypeId,
PdbByteReader reader) throws PdbException, CancelledException {
pdb.getPdbReaderMetrics().witnessSymbolTypeId(symbolTypeId);

View File

@ -76,11 +76,19 @@ public class SymbolRecords {
int streamNumber;
PdbByteReader reader;
streamNumber = pdb.getDebugInfo().getSymbolRecordsStreamNumber();
reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
symbolsByOffset = deserializeSymbolRecords(reader, monitor);
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
streamNumber = debugInfo.getSymbolRecordsStreamNumber();
if (streamNumber <= 0) {
return;
}
for (AbstractModuleInformation module : pdb.getDebugInfo().moduleInformationList) {
reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
symbolsByOffset = deserializeSymbolRecords(pdb, reader, monitor);
for (AbstractModuleInformation module : debugInfo.moduleInformationList) {
streamNumber = module.getStreamNumberDebugInformation();
if (streamNumber != 0xffff) {
// System.out.println("\n\nStreamNumber: " + streamNumber);
@ -90,7 +98,7 @@ public class SymbolRecords {
sizeDebug -= x; //TODO: seems right, but need to evaluate this
PdbByteReader debugReader = reader.getSubPdbByteReader(sizeDebug);
Map<Long, AbstractMsSymbol> oneModuleSymbolsByOffset =
deserializeSymbolRecords(debugReader, monitor);
deserializeSymbolRecords(pdb, debugReader, monitor);
moduleSymbolsByOffset.add(oneModuleSymbolsByOffset);
// TODO: figure out the rest of the bytes in the stream
// As of 20190618: feel that this is where we will find C11Lines or C13Lines
@ -109,27 +117,28 @@ public class SymbolRecords {
* Deserializes the {@link AbstractMsSymbol} symbols from the {@link PdbByteReader} and
* returns a {@link Map}&lt;{@link Long},{@link AbstractMsSymbol}&gt; of buffer offsets to
* symbols.
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize.
* @param monitor {@link TaskMonitor} used for checking cancellation.
* @return map of buffer offsets to {@link AbstractMsSymbol symbols}.
* @throws PdbException Upon not enough data left to parse.
* @throws CancelledException Upon user cancellation.
*/
public Map<Long, AbstractMsSymbol> deserializeSymbolRecords(PdbByteReader reader,
TaskMonitor monitor) throws PdbException, CancelledException {
public static Map<Long, AbstractMsSymbol> deserializeSymbolRecords(AbstractPdb pdb,
PdbByteReader reader, TaskMonitor monitor) throws PdbException, CancelledException {
Objects.requireNonNull(pdb, "pdb cannot be null");
//System.out.println(reader.dump(0x400));
SymbolParser parser = pdb.getSymbolParser();
Map<Long, AbstractMsSymbol> mySymbolsByOffset = new TreeMap<>();
while (reader.hasMore()) {
monitor.checkCanceled();
// Including length in byte array for alignment purposes.
// Including length in byte array for alignment purposes.
int offset = reader.getIndex();
int recordLength = reader.parseUnsignedShortVal();
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
recordReader.markAlign(2);
AbstractMsSymbol symbol = parser.parse(recordReader);
AbstractMsSymbol symbol = SymbolParser.parse(pdb, recordReader);
mySymbolsByOffset.put((long) offset, symbol);
}
return mySymbolsByOffset;

View File

@ -26,34 +26,28 @@ import ghidra.util.exception.CancelledException;
*/
public class TypeParser {
//==============================================================================================
// Internals
//==============================================================================================
protected AbstractPdb pdb;
//==============================================================================================
// API
//==============================================================================================
/**
* Constructor.
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
*/
public TypeParser(AbstractPdb pdb) {
Objects.requireNonNull(pdb, "pdb cannot be null");
this.pdb = pdb;
private TypeParser() {
}
/**
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
* @param pdb {@link AbstractPdb} that owns the Types to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the data.
* @param recordNumber {@link RecordNumber} of the record.
* @return {@link AbstractMsType} parsed.
* @throws PdbException upon error parsing a field.
* @throws CancelledException Upon user cancellation.
*/
public AbstractMsType parseRecord(PdbByteReader reader, RecordNumber recordNumber)
throws PdbException, CancelledException {
AbstractMsType result = parse(reader, AbstractMsType.class);
public static AbstractMsType parseRecord(AbstractPdb pdb, PdbByteReader reader,
RecordNumber recordNumber) throws PdbException, CancelledException {
Objects.requireNonNull(pdb, "pdb cannot be null");
AbstractMsType result = parse(pdb, reader, AbstractMsType.class);
result.setRecordNumber(recordNumber);
return result;
}
@ -61,25 +55,29 @@ public class TypeParser {
/**
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it
* as a {@link MsTypeField}.
* @param pdb {@link AbstractPdb} that owns the Types to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the data.
* @return {@link MsTypeField} parsed.
* @throws PdbException upon error parsing a field.
* @throws CancelledException Upon user cancellation.
*/
public MsTypeField parseField(PdbByteReader reader) throws PdbException, CancelledException {
MsTypeField result = parse(reader, MsTypeField.class);
public static MsTypeField parseField(AbstractPdb pdb, PdbByteReader reader)
throws PdbException, CancelledException {
MsTypeField result = parse(pdb, reader, MsTypeField.class);
return result;
}
/**
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
* @param pdb {@link AbstractPdb} that owns the Types to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the data.
* @return {@link AbstractMsType} parsed.
* @throws PdbException upon error parsing dataTypeId.
* @throws CancelledException Upon user cancellation.
*/
public AbstractMsType parse(PdbByteReader reader) throws PdbException, CancelledException {
AbstractMsType result = parse(reader, AbstractMsType.class);
public static AbstractMsType parse(AbstractPdb pdb, PdbByteReader reader)
throws PdbException, CancelledException {
AbstractMsType result = parse(pdb, reader, AbstractMsType.class);
return result;
}
@ -89,18 +87,19 @@ public class TypeParser {
* @param <T> the required type to be returned. IMPORTANT: T must only be one of:
* {@link AbstractMsType} or {@link MsTypeField} or something else in common with
* {@link BadMsType}, otherwise a Bad Cast Exception might occur.
* @param pdb {@link AbstractPdb} that owns the Types to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the data.
* @param requiredClass the required type to be returned.
* @param requiredClass the required type to be returned.
* @return an instance of type T or type T version of BadMsType. IMPORTANT: See restriction
* on T.
* @throws PdbException upon error parsing dataTypeId.
* @throws CancelledException Upon user cancellation.
*/
private <T> T parse(PdbByteReader reader, Class<T> requiredClass)
private static <T> T parse(AbstractPdb pdb, PdbByteReader reader, Class<T> requiredClass)
throws PdbException, CancelledException {
int dataTypeId = reader.parseUnsignedShortVal();
try {
IdMsParsable parsable = parse(reader, dataTypeId);
IdMsParsable parsable = parse(pdb, reader, dataTypeId);
if (requiredClass.isInstance(parsable)) {
return requiredClass.cast(parsable);
}
@ -114,13 +113,14 @@ public class TypeParser {
/**
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
* @param pdb {@link AbstractPdb} that owns the Types to be parsed.
* @param reader {@link PdbByteReader} from which to deserialize the data.
* @param dataTypeId the PDB ID for the symbol type to be parsed.
* @return {@link AbstractMsType} parsed.
* @throws PdbException upon error parsing a field.
* @throws CancelledException Upon user cancellation.
*/
private IdMsParsable parse(PdbByteReader reader, int dataTypeId)
private static IdMsParsable parse(AbstractPdb pdb, PdbByteReader reader, int dataTypeId)
throws PdbException, CancelledException {
pdb.getPdbReaderMetrics().witnessDataTypeId(dataTypeId);
@ -418,7 +418,7 @@ public class TypeParser {
type = new ManagedStMsType(pdb, reader);
break;
// 0x1500 block
// 0x1500 block
case TypeServerMsType.PDB_ID:
type = new TypeServerMsType(pdb, reader);
break;
@ -507,7 +507,7 @@ public class TypeParser {
type = new VirtualFunctionTableMsType(pdb, reader);
break;
// 0x1600 block
// 0x1600 block
case FunctionIdMsType.PDB_ID:
type = new FunctionIdMsType(pdb, reader);
break;

View File

@ -95,7 +95,7 @@ public class DiscardedByLinkMsSymbol extends AbstractMsSymbol {
// SymbolParser parser = new SymbolParser(pdb);
// symbolList = parser.deserializeSymbolRecords(dataReader);
symbolList = getOrderedSymbols(
pdb.getSymbolRecords().deserializeSymbolRecords(dataReader, TaskMonitor.DUMMY));
SymbolRecords.deserializeSymbolRecords(pdb, dataReader, TaskMonitor.DUMMY));
}
/**

View File

@ -51,8 +51,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
throws PdbException, CancelledException {
super(pdb, reader);
while (reader.hasMore()) {
MsTypeField type = pdb.getTypeParser().parseField(reader);
// AbstractMsType type = pdb.getTypeParser().parse(reader);
MsTypeField type = TypeParser.parseField(pdb, reader);
if ((type instanceof AbstractBaseClassMsType) ||
(type instanceof AbstractVirtualBaseClassMsType) ||
(type instanceof AbstractIndirectVirtualBaseClassMsType)) {
@ -85,7 +84,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
}
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of base class types.
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of base class types.
* @return List of base class types.
*/
public List<MsTypeField> getBaseClassList() {
@ -94,7 +93,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of type members types of
* this field list.
* this field list.
* @return Field list.
*/
public List<MsTypeField> getMemberList() {
@ -103,7 +102,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
/**
* Returns the (ordered?) {@link List}&lt;{@link AbstractMsType}&gt; of other types. (We have
* separated these out, but are unsure about what they are at this time.)
* separated these out, but are unsure about what they are at this time.)
* @return List of other types.
*/
public List<MsTypeField> getMethodList() {

View File

@ -45,7 +45,7 @@ public class ReferencedSymbolMsType extends AbstractMsType {
super(pdb, reader);
int recordLength = reader.parseUnsignedShortVal();
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
symbolRecord = pdb.getSymbolParser().parse(recordReader);
symbolRecord = SymbolParser.parse(pdb, recordReader);
}
@Override

View File

@ -327,10 +327,14 @@ public class PdbAddressManager {
// }
private void determineMemoryBlocks() {
PdbDebugInfo dbi = applicator.getPdb().getDebugInfo();
segmentMapList = dbi.getSegmentMapList();
if (dbi instanceof PdbNewDebugInfo) {
DebugData debugData = ((PdbNewDebugInfo) dbi).getDebugData();
AbstractPdb pdb = applicator.getPdb();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
segmentMapList = debugInfo.getSegmentMapList();
if (debugInfo instanceof PdbNewDebugInfo) {
DebugData debugData = ((PdbNewDebugInfo) debugInfo).getDebugData();
imageSectionHeaders = debugData.getImageSectionHeadersOrig();
if (imageSectionHeaders != null) {
omapFromSource = debugData.getOmapFromSource();
@ -504,6 +508,10 @@ public class PdbAddressManager {
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
AbstractPdb pdb = applicator.getPdb();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
Program program = applicator.getProgram();
if (program == null) {
return;
@ -511,7 +519,7 @@ public class PdbAddressManager {
Memory mem = program.getMemory();
MemoryBlock[] blocks = mem.getBlocks();
List<SegmentMapDescription> segmentMapList = pdb.getDebugInfo().getSegmentMapList();
List<SegmentMapDescription> segmentMapList = debugInfo.getSegmentMapList();
/**
* Program has additional "Headers" block set up by the {@link PeLoader}.
*/
@ -570,7 +578,9 @@ public class PdbAddressManager {
@SuppressWarnings("unused") // for method not being called.
private boolean garnerSectionSegmentInformation() throws PdbException {
AbstractPdb pdb = applicator.getPdb();
if (pdb.getDebugInfo() == null) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return false;
}
@ -578,10 +588,13 @@ public class PdbAddressManager {
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
int num = 1;
for (AbstractModuleInformation module : pdb.getDebugInfo().getModuleInformationList()) {
for (AbstractModuleInformation module : debugInfo.getModuleInformationList()) {
if ("* Linker *".equals(module.getModuleName())) {
List<AbstractMsSymbol> linkerSymbolList =
applicator.getSymbolGroupForModule(num).getSymbols();
SymbolGroup symbolGroup = applicator.getSymbolGroupForModule(num);
if (symbolGroup == null) {
continue; // should not happen
}
List<AbstractMsSymbol> linkerSymbolList = symbolGroup.getSymbols();
for (AbstractMsSymbol symbol : linkerSymbolList) {
if (symbol instanceof PeCoffSectionMsSymbol) {
PeCoffSectionMsSymbol section = (PeCoffSectionMsSymbol) symbol;

View File

@ -377,12 +377,16 @@ public class PdbApplicator {
private List<SymbolGroup> createSymbolGroups() throws CancelledException, PdbException {
List<SymbolGroup> mySymbolGroups = new ArrayList<>();
int num = pdb.getDebugInfo().getNumModules();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return mySymbolGroups;
}
int num = debugInfo.getNumModules();
// moduleNumber zero is our global/public group.
for (int moduleNumber = 0; moduleNumber <= num; moduleNumber++) {
monitor.checkCanceled();
Map<Long, AbstractMsSymbol> symbols =
pdb.getDebugInfo().getModuleSymbolsByOffset(moduleNumber);
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(moduleNumber);
SymbolGroup symbolGroup = new SymbolGroup(symbols, moduleNumber);
mySymbolGroups.add(symbolGroup);
}
@ -585,11 +589,16 @@ public class PdbApplicator {
throws CancelledException, PdbException {
List<String> categoryNames = new ArrayList<>();
int num = pdb.getDebugInfo().getNumModules();
for (int index = 1; index <= num; index++) {
monitor.checkCanceled();
String moduleName = pdb.getDebugInfo().getModuleInformation(index).getModuleName();
categoryNames.add(moduleName);
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo != null) {
int num = debugInfo.getNumModules();
for (int index = 1; index <= num; index++) {
monitor.checkCanceled();
String moduleName = debugInfo.getModuleInformation(index).getModuleName();
categoryNames.add(moduleName);
}
}
int index = pdbFilename.lastIndexOf("\\");
@ -655,7 +664,13 @@ public class PdbApplicator {
//==============================================================================================
//==============================================================================================
int findModuleNumberBySectionOffsetContribution(int section, long offset) throws PdbException {
for (AbstractSectionContribution sectionContribution : pdb.getDebugInfo().getSectionContributionList()) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
throw new PdbException("PDB: DebugInfo is null");
}
for (AbstractSectionContribution sectionContribution : debugInfo
.getSectionContributionList()) {
int sectionContributionOffset = sectionContribution.getOffset();
int maxSectionContributionOffset =
sectionContributionOffset + sectionContribution.getLength();
@ -675,8 +690,8 @@ public class PdbApplicator {
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
monitor.initialize(num);
setMonitorMessage("PDB: Processing " + num + " data type components...");
for (int indexNumber =
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
.getTypeIndexMaxExclusive(); indexNumber++) {
monitor.checkCanceled();
//PdbResearch.checkBreak(indexNumber);
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
@ -742,8 +757,8 @@ public class PdbApplicator {
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
monitor.initialize(num);
setMonitorMessage("PDB: Processing " + num + " item type components...");
for (int indexNumber =
ipi.getTypeIndexMin(); indexNumber < ipi.getTypeIndexMaxExclusive(); indexNumber++) {
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
.getTypeIndexMaxExclusive(); indexNumber++) {
monitor.checkCanceled();
MsTypeApplier applier = getTypeApplier(RecordNumber.itemRecordNumber(indexNumber));
applier.apply();
@ -785,8 +800,8 @@ public class PdbApplicator {
setMonitorMessage("PDB: Resolving " + num + " data type components...");
Date start = new Date();
long longStart = start.getTime();
for (int indexNumber =
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
.getTypeIndexMaxExclusive(); indexNumber++) {
monitor.checkCanceled();
//PdbResearch.checkBreak(indexNumber);
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
@ -822,6 +837,9 @@ public class PdbApplicator {
}
SymbolGroup getSymbolGroupForModule(int moduleNumber) {
if (moduleNumber < 0 || moduleNumber >= symbolGroups.size()) {
return null;
}
return symbolGroups.get(moduleNumber);
}
@ -992,7 +1010,7 @@ public class PdbApplicator {
@SuppressWarnings("unused") // for method not being called.
/**
* Process all symbols. User should not then call other methods:
* {@link #processGlobalSymbols()}, (@link #processPublicSymbols()}, and
* {@link #processGlobalSymbolsNoTypedefs()}, (@link #processPublicSymbols()}, and
* {@link #processNonPublicOrGlobalSymbols()}.
* @throws CancelledException upon user cancellation
* @throws PdbException upon issue processing the request
@ -1007,6 +1025,9 @@ public class PdbApplicator {
private void processMainSymbols() throws CancelledException, PdbException {
// Get a count
SymbolGroup symbolGroup = getSymbolGroup();
if (symbolGroup == null) {
return;
}
int totalCount = symbolGroup.size();
setMonitorMessage("PDB: Applying " + totalCount + " main symbol components...");
monitor.initialize(totalCount);
@ -1016,11 +1037,19 @@ public class PdbApplicator {
//==============================================================================================
private void processModuleSymbols() throws CancelledException {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
int totalCount = 0;
int num = pdb.getDebugInfo().getNumModules();
int num = debugInfo.getNumModules();
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
monitor.checkCanceled();
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
if (symbolGroup == null) {
continue; // should not happen
}
totalCount += symbolGroup.size();
}
setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
@ -1031,6 +1060,9 @@ public class PdbApplicator {
monitor.checkCanceled();
// Process module symbols list
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
if (symbolGroup == null) {
continue; // should not happen
}
AbstractMsSymbolIterator iter = symbolGroup.iterator();
processSymbolGroup(moduleNumber, iter);
// catelogSymbols(index, symbolGroup);
@ -1073,10 +1105,17 @@ public class PdbApplicator {
*/
private void processPublicSymbols() throws CancelledException, PdbException {
SymbolGroup symbolGroup = getSymbolGroup();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
PublicSymbolInformation publicSymbolInformation =
pdb.getDebugInfo().getPublicSymbolInformation();
SymbolGroup symbolGroup = getSymbolGroup();
if (symbolGroup == null) {
return;
}
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
setMonitorMessage("PDB: Applying " + offsets.size() + " public symbol components...");
monitor.initialize(offsets.size());
@ -1103,10 +1142,17 @@ public class PdbApplicator {
*/
private void processGlobalSymbolsNoTypedefs() throws CancelledException, PdbException {
SymbolGroup symbolGroup = getSymbolGroup();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation =
pdb.getDebugInfo().getGlobalSymbolInformation();
SymbolGroup symbolGroup = getSymbolGroup();
if (symbolGroup == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
setMonitorMessage("PDB: Applying global symbols...");
monitor.initialize(offsets.size());
@ -1134,10 +1180,17 @@ public class PdbApplicator {
*/
private void processGlobalTypdefSymbols() throws CancelledException, PdbException {
SymbolGroup symbolGroup = getSymbolGroup();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation =
pdb.getDebugInfo().getGlobalSymbolInformation();
SymbolGroup symbolGroup = getSymbolGroup();
if (symbolGroup == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
setMonitorMessage("PDB: Applying typedefs...");
monitor.initialize(offsets.size());
@ -1166,12 +1219,24 @@ public class PdbApplicator {
*/
@SuppressWarnings("unused") // for method not being called.
private void processNonPublicOrGlobalSymbols() throws CancelledException, PdbException {
Set<Long> offsetsRemaining = getSymbolGroup().getOffsets();
for (long off : pdb.getDebugInfo().getPublicSymbolInformation().getModifiedHashRecordSymbolOffsets()) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
SymbolGroup symbolGroup = getSymbolGroup();
if (symbolGroup == null) {
return;
}
Set<Long> offsetsRemaining = symbolGroup.getOffsets();
for (long off : debugInfo.getPublicSymbolInformation()
.getModifiedHashRecordSymbolOffsets()) {
monitor.checkCanceled();
offsetsRemaining.remove(off);
}
for (long off : pdb.getDebugInfo().getGlobalSymbolInformation().getModifiedHashRecordSymbolOffsets()) {
for (long off : debugInfo.getGlobalSymbolInformation()
.getModifiedHashRecordSymbolOffsets()) {
monitor.checkCanceled();
offsetsRemaining.remove(off);
}
@ -1181,7 +1246,6 @@ public class PdbApplicator {
monitor.initialize(offsetsRemaining.size());
//getCategoryUtils().setModuleTypedefsCategory(null);
SymbolGroup symbolGroup = getSymbolGroup();
AbstractMsSymbolIterator iter = symbolGroup.iterator();
for (long offset : offsetsRemaining) {
monitor.checkCanceled();
@ -1194,9 +1258,10 @@ public class PdbApplicator {
//==============================================================================================
private int findLinkerModuleNumber() {
if (pdb.getDebugInfo() != null) {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo != null) {
int num = 1;
for (AbstractModuleInformation module : pdb.getDebugInfo().getModuleInformationList()) {
for (AbstractModuleInformation module : debugInfo.getModuleInformationList()) {
if (isLinkerModule(module.getModuleName())) {
return num;
}
@ -1242,16 +1307,24 @@ public class PdbApplicator {
//==============================================================================================
private void processThunkSymbolsFromNonLinkerModules() throws CancelledException {
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
int linkerModuleNumber = findLinkerModuleNumber();
int totalCount = 0;
int num = pdb.getDebugInfo().getNumModules();
int num = debugInfo.getNumModules();
for (int index = 1; index <= num; index++) {
monitor.checkCanceled();
if (index == linkerModuleNumber) {
continue;
}
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
if (symbolGroup == null) {
continue; // should not happen
}
totalCount += symbolGroup.size();
}
setMonitorMessage("PDB: Processing module thunks...");
@ -1264,6 +1337,9 @@ public class PdbApplicator {
continue;
}
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
if (symbolGroup == null) {
continue; // should not happen
}
AbstractMsSymbolIterator iter = symbolGroup.iterator();
while (iter.hasNext()) {
monitor.checkCanceled();

View File

@ -334,8 +334,8 @@ public class PdbResearch {
static void checkBreak(int recordNumber, MsTypeApplier applier) {
String nn = applier.getMsType().getName();
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>".equals(
nn)) {
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>"
.equals(nn)) {
doNothingSetBreakPointHere();
}
if ("class std::__1::__iostream_category".equals(nn)) {
@ -411,9 +411,18 @@ public class PdbResearch {
//==============================================================================================
static void childWalk(PdbApplicator applicator, TaskMonitor monitor)
throws CancelledException, PdbException {
PdbDebugInfo debugInfo = applicator.getPdb().getDebugInfo();
if (debugInfo == null) {
return;
}
SymbolGroup symbolGroup = applicator.getSymbolGroup();
GlobalSymbolInformation globalSymbolInformation =
applicator.getPdb().getDebugInfo().getGlobalSymbolInformation();
if (symbolGroup == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
applicator.setMonitorMessage("PDB: Applying typedefs...");
monitor.initialize(offsets.size());
@ -449,6 +458,9 @@ public class PdbResearch {
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
AbstractMsSymbolIterator refIter =
refSymbolApplier.getInitializedReferencedSymbolGroupIterator();
if (refIter == null) {
throw new PdbException("PDB: Referenced Symbol Error - not refIter");
}
// recursion
childWalkSym(applicator, refIter.getModuleNumber(), refIter);
}
@ -616,10 +628,18 @@ public class PdbResearch {
private static void processPublicSymbols(PdbApplicator applicator,
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
AbstractPdb pdb = applicator.getPdb();
SymbolGroup symbolGroup = applicator.getSymbolGroup();
PublicSymbolInformation publicSymbolInformation =
pdb.getDebugInfo().getPublicSymbolInformation();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
SymbolGroup symbolGroup = applicator.getSymbolGroup();
if (symbolGroup == null) {
return;
}
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
applicator.setMonitorMessage(
"PDB: Applying " + offsets.size() + " public symbol components...");
@ -643,10 +663,18 @@ public class PdbResearch {
private static void processGlobalSymbols(PdbApplicator applicator,
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
AbstractPdb pdb = applicator.getPdb();
SymbolGroup symbolGroup = applicator.getSymbolGroup();
GlobalSymbolInformation globalSymbolInformation =
pdb.getDebugInfo().getGlobalSymbolInformation();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
SymbolGroup symbolGroup = applicator.getSymbolGroup();
if (symbolGroup == null) {
return;
}
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
applicator.setMonitorMessage("PDB: Applying global symbols...");
monitor.initialize(offsets.size());
@ -669,8 +697,13 @@ public class PdbResearch {
private static void processModuleSymbols(PdbApplicator applicator,
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
AbstractPdb pdb = applicator.getPdb();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return;
}
int totalCount = 0;
int num = pdb.getDebugInfo().getNumModules();
int num = debugInfo.getNumModules();
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
monitor.checkCanceled();
SymbolGroup symbolGroup = applicator.getSymbolGroupForModule(moduleNumber);
@ -679,8 +712,8 @@ public class PdbResearch {
}
totalCount += symbolGroup.size();
}
applicator.setMonitorMessage(
"PDB: Applying " + totalCount + " module symbol components...");
applicator
.setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
monitor.initialize(totalCount);
// Process symbols list for each module
@ -867,7 +900,8 @@ public class PdbResearch {
// if count is zero for a definition, then, the field list record
// number refers to an actual field list.
// So... seems we can trust forward reference and ignore count.
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
if (compType
.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
doNothingSetBreakPointHere();
}
}
@ -912,7 +946,8 @@ public class PdbResearch {
// the field list record number refers to an actual field
// list. So... seems we can trust forward reference and
// ignore count.
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
if (compType
.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
doNothingSetBreakPointHere();
}
}

View File

@ -53,11 +53,20 @@ public class PdbVbtManager extends VbtManager {
throws CancelledException {
TaskMonitor monitor = applicator.getMonitor();
SymbolGroup symbolGroup = applicator.getSymbolGroup();
Map<String, Address> myAddressByMangledName = new HashMap<>();
PublicSymbolInformation publicSymbolInformation =
applicator.getPdb().getDebugInfo().getPublicSymbolInformation();
AbstractPdb pdb = applicator.getPdb();
PdbDebugInfo debugInfo = pdb.getDebugInfo();
if (debugInfo == null) {
return myAddressByMangledName;
}
SymbolGroup symbolGroup = applicator.getSymbolGroup();
if (symbolGroup == null) {
return myAddressByMangledName;
}
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
applicator.setMonitorMessage("PDB: Searching for virtual base table symbols...");
monitor.initialize(offsets.size());

View File

@ -53,11 +53,17 @@ public class ReferenceSymbolApplier extends MsSymbolApplier {
void apply() throws CancelledException, PdbException {
// Potential recursive call via applicator.procSym().
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator();
if (refIter == null) {
throw new PdbException("PDB: Referenced Symbol Error - null refIter");
}
applicator.procSym(refIter);
}
AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() {
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
if (refSymbolGroup == null) {
return null;
}
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
return refIter;