mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-09-20 09:31:47 +00:00
GP-1827 - Fix NPE for null PDB DBI; static symbol/type parsing methods help remedy
This commit is contained in:
parent
07a9878b94
commit
d86b60e6b2
|
@ -122,8 +122,8 @@ public class PdbQuery {
|
||||||
TaskMonitor monitor = script.getMonitor();
|
TaskMonitor monitor = script.getMonitor();
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
println(script, "Searching " + num + " PDB data type components...");
|
println(script, "Searching " + num + " PDB data type components...");
|
||||||
for (int indexNumber =
|
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
|
||||||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
RecordNumber recordNumber = RecordNumber.typeRecordNumber(indexNumber);
|
RecordNumber recordNumber = RecordNumber.typeRecordNumber(indexNumber);
|
||||||
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
|
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
|
||||||
|
@ -161,8 +161,8 @@ public class PdbQuery {
|
||||||
TaskMonitor monitor = script.getMonitor();
|
TaskMonitor monitor = script.getMonitor();
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
println(script, "Searching " + num + " PDB item type components...");
|
println(script, "Searching " + num + " PDB item type components...");
|
||||||
for (int indexNumber =
|
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
|
||||||
ipi.getTypeIndexMin(); indexNumber < ipi.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
RecordNumber recordNumber = RecordNumber.itemRecordNumber(indexNumber);
|
RecordNumber recordNumber = RecordNumber.itemRecordNumber(indexNumber);
|
||||||
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
|
AbstractMsType typeRecord = pdb.getTypeRecord(recordNumber);
|
||||||
|
@ -188,17 +188,21 @@ public class PdbQuery {
|
||||||
public static void searchSymbols(GhidraScript script, AbstractPdb pdb, String searchString)
|
public static void searchSymbols(GhidraScript script, AbstractPdb pdb, String searchString)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder results = new StringBuilder();
|
StringBuilder results = new StringBuilder();
|
||||||
results.append('\n');
|
results.append('\n');
|
||||||
|
|
||||||
int numModules = pdb.getDebugInfo().getNumModules();
|
int numModules = debugInfo.getNumModules();
|
||||||
TaskMonitor monitor = script.getMonitor();
|
TaskMonitor monitor = script.getMonitor();
|
||||||
int numSymbols = 0;
|
int numSymbols = 0;
|
||||||
for (int module = 0; module <= numModules; module++) {
|
for (int module = 0; module <= numModules; module++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
try {
|
try {
|
||||||
Map<Long, AbstractMsSymbol> symbols =
|
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(module);
|
||||||
pdb.getDebugInfo().getModuleSymbolsByOffset(module);
|
|
||||||
numSymbols += symbols.size();
|
numSymbols += symbols.size();
|
||||||
}
|
}
|
||||||
catch (PdbException e) {
|
catch (PdbException e) {
|
||||||
|
@ -211,8 +215,7 @@ public class PdbQuery {
|
||||||
for (int module = 0; module <= numModules; module++) {
|
for (int module = 0; module <= numModules; module++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
try {
|
try {
|
||||||
Map<Long, AbstractMsSymbol> symbols =
|
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(module);
|
||||||
pdb.getDebugInfo().getModuleSymbolsByOffset(module);
|
|
||||||
numSymbols += symbols.size();
|
numSymbols += symbols.size();
|
||||||
for (Map.Entry<Long, AbstractMsSymbol> entry : symbols.entrySet()) {
|
for (Map.Entry<Long, AbstractMsSymbol> entry : symbols.entrySet()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
|
@ -86,9 +86,6 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
|
|
||||||
protected boolean substreamsDeserialized = false;
|
protected boolean substreamsDeserialized = false;
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
private TypeParser typeParser;
|
|
||||||
private SymbolParser symbolParser;
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// Ghidra-specific:
|
// Ghidra-specific:
|
||||||
private PdbReaderMetrics pdbReaderMetrics = new PdbReaderMetrics(this);
|
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.
|
* @return {@link PdbIdentifiers} of information.
|
||||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||||
* inability to read required bytes.
|
* inability to read required bytes.
|
||||||
|
@ -151,7 +148,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
parseDBI();
|
parseDBI();
|
||||||
if (debugInfo != null) {
|
if (debugInfo != null) {
|
||||||
try {
|
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);
|
debugInfo.deserialize(true, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
catch (CancelledException e) {
|
catch (CancelledException e) {
|
||||||
|
@ -198,22 +195,6 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
PdbLog.message(pdbReaderMetrics::getPostProcessingReport);
|
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.
|
* Returns the Version Number of the PDB.
|
||||||
* @return 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
|
// TODO: this method should be package protected
|
||||||
public void setTargetProcessor(Processor targetProcessorIn) {
|
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
|
* {@link ImageFileMachine}) should be processed and laid down first. Subsequent values
|
||||||
* can come from {@link AbstractCompile2MsSymbol} and {@link Compile3MsSymbol}. Note:
|
* can come from {@link AbstractCompile2MsSymbol} and {@link Compile3MsSymbol}. Note:
|
||||||
* {@link PdbDebugInfo} does not carry {@link ImageFileMachine}, and thus no mapping
|
* {@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})
|
* Returns the ItemProgramInterface (of type {@link AbstractTypeProgramInterface})
|
||||||
* component.
|
* component.
|
||||||
* @return ItemProgramInterface (of type {@link AbstractTypeProgramInterface}) component
|
* @return ItemProgramInterface (of type {@link AbstractTypeProgramInterface}) component
|
||||||
* or null if not available.
|
* or null if not available.
|
||||||
*/
|
*/
|
||||||
public AbstractTypeProgramInterface getItemProgramInterface() {
|
public AbstractTypeProgramInterface getItemProgramInterface() {
|
||||||
|
@ -327,14 +308,6 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
return debugInfo;
|
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
|
* Returns the record for the associated record number, which is expected to match the
|
||||||
* desired class
|
* desired class
|
||||||
|
@ -441,7 +414,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||||
* @return Version number.
|
* @return Version number.
|
||||||
* @throws IOException on file I/O issues.
|
* @throws IOException on file I/O issues.
|
||||||
* @throws PdbException on parsing issues.
|
* @throws PdbException on parsing issues.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
static int deserializeVersionNumber(AbstractMsf msf, TaskMonitor monitor)
|
static int deserializeVersionNumber(AbstractMsf msf, TaskMonitor monitor)
|
||||||
|
@ -469,14 +442,11 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
strings = new ArrayList<>();
|
strings = new ArrayList<>();
|
||||||
parameters = new ArrayList<>();
|
parameters = new ArrayList<>();
|
||||||
nameTable = new NameTable(this);
|
nameTable = new NameTable(this);
|
||||||
|
|
||||||
typeParser = new TypeParser(this);
|
|
||||||
symbolParser = new SymbolParser(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes the main {@link PdbIdentifiers} found in the PDB Directory from the
|
* Deserializes the main {@link PdbIdentifiers} found in the PDB Directory from the
|
||||||
* {@link PdbByteReader}.
|
* {@link PdbByteReader}.
|
||||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||||
* inability to read required bytes.
|
* inability to read required bytes.
|
||||||
|
@ -494,7 +464,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||||
return msf;
|
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.
|
* Deserializes the sub-streams for this {@link AbstractPdb} object.
|
||||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||||
|
|
|
@ -168,7 +168,11 @@ public abstract class AbstractSymbolInformation {
|
||||||
protected void generateSymbolsList(TaskMonitor monitor)
|
protected void generateSymbolsList(TaskMonitor monitor)
|
||||||
throws PdbException, CancelledException {
|
throws PdbException, CancelledException {
|
||||||
symbols = new ArrayList<>();
|
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) {
|
for (SymbolHashRecord record : hashRecords) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
long offset = record.getOffset() - 2; // Modified offset
|
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 reader {@link PdbByteReader} containing the data buffer to process.
|
||||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||||
* @throws PdbException Upon not enough data left to parse.
|
* @throws PdbException Upon not enough data left to parse.
|
||||||
|
|
|
@ -265,7 +265,6 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
||||||
throws PdbException, CancelledException {
|
throws PdbException, CancelledException {
|
||||||
int recordLength;
|
int recordLength;
|
||||||
int recordNumber = typeIndexMin;
|
int recordNumber = typeIndexMin;
|
||||||
TypeParser parser = pdb.getTypeParser();
|
|
||||||
|
|
||||||
while (reader.hasMore()) {
|
while (reader.hasMore()) {
|
||||||
monitor.checkCanceled();
|
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:
|
// know which of the two to call, and we'd have to create an AbstractTypeIndex:
|
||||||
// parseTypeRecordNumber(recordReader, recordNumber);
|
// parseTypeRecordNumber(recordReader, recordNumber);
|
||||||
// parseItemRecordNumber(recordReader, recordNumber);
|
// parseItemRecordNumber(recordReader, recordNumber);
|
||||||
AbstractMsType type =
|
AbstractMsType type = TypeParser.parseRecord(pdb, recordReader,
|
||||||
parser.parseRecord(recordReader, RecordNumber.make(recordCategory, recordNumber));
|
RecordNumber.make(recordCategory, recordNumber));
|
||||||
typeList.add(type);
|
typeList.add(type);
|
||||||
recordNumber++;
|
recordNumber++;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +391,7 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
||||||
throws IOException, PdbException, CancelledException {
|
throws IOException, PdbException, CancelledException {
|
||||||
// I don't believe we need to parse and process the hash table. They seemingly are
|
// 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
|
// 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.
|
// them as we read each record buffer.
|
||||||
// Note that we have no evidence of how the Auxiliary stream is used. Its
|
// 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
|
// contents might need to get concatenated with the contents of the primary
|
||||||
|
|
|
@ -137,7 +137,7 @@ public class DebugData {
|
||||||
* each particular debug type (e.g., the first stream number read is for the stream containing
|
* 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
|
* 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
|
* 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
|
* {@link #deserialize(TaskMonitor)} method deserializes each of these streams
|
||||||
* that are valid to the corresponding debug data type.
|
* that are valid to the corresponding debug data type.
|
||||||
* @param reader {@link PdbByteReader} from which to parse the header.
|
* @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
|
// TODO: More work possible. See XData processing and notes there. This is very
|
||||||
// incomplete.
|
// incomplete.
|
||||||
if (pdb.getDebugInfo() instanceof PdbNewDebugInfo) {
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo instanceof PdbNewDebugInfo) {
|
||||||
//Processor target = pdb.getTargetProcessor();
|
//Processor target = pdb.getTargetProcessor();
|
||||||
PdbNewDebugInfo dbi = (PdbNewDebugInfo) pdb.getDebugInfo();
|
PdbNewDebugInfo dbi = (PdbNewDebugInfo) debugInfo;
|
||||||
ImageFileMachine machine = dbi.getMachineType();
|
ImageFileMachine machine = dbi.getMachineType();
|
||||||
switch (machine) {
|
switch (machine) {
|
||||||
case IA64:
|
case IA64:
|
||||||
|
|
|
@ -877,8 +877,12 @@ public class PdbReaderMetrics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void witnessedSectionSegmentNumber(int segment) {
|
public void witnessedSectionSegmentNumber(int segment) {
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (numSegments == -1) {
|
if (numSegments == -1) {
|
||||||
numSegments = pdb.getDebugInfo().getSegmentMapList().size();
|
numSegments = debugInfo.getSegmentMapList().size();
|
||||||
}
|
}
|
||||||
if (segment < 0 || segment > numSegments) {
|
if (segment < 0 || segment > numSegments) {
|
||||||
PdbLog.message("segment " + segment + " out of range [0," + numSegments + ")");
|
PdbLog.message("segment " + segment + " out of range [0," + numSegments + ")");
|
||||||
|
|
|
@ -26,35 +26,30 @@ import ghidra.util.exception.CancelledException;
|
||||||
*/
|
*/
|
||||||
public class SymbolParser {
|
public class SymbolParser {
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
// Internals
|
|
||||||
//==============================================================================================
|
|
||||||
private AbstractPdb pdb;
|
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// API
|
// API
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
|
|
||||||
*/
|
*/
|
||||||
public SymbolParser(AbstractPdb pdb) {
|
private SymbolParser() {
|
||||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
|
||||||
this.pdb = pdb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsSymbol} from the {@link PdbByteReader} and returns it.
|
* 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.
|
* @param reader {@link PdbByteReader} from which to deserialize the symbol record.
|
||||||
* @return {@link AbstractMsSymbol} that was parsed.
|
* @return {@link AbstractMsSymbol} that was parsed.
|
||||||
* @throws PdbException upon error parsing a field.
|
* @throws PdbException upon error parsing a field.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @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();
|
int symbolTypeId = reader.parseUnsignedShortVal();
|
||||||
AbstractMsSymbol symbol;
|
AbstractMsSymbol symbol;
|
||||||
try {
|
try {
|
||||||
symbol = parseRecord(symbolTypeId, reader);
|
symbol = parseRecord(pdb, symbolTypeId, reader);
|
||||||
}
|
}
|
||||||
catch (PdbException e) {
|
catch (PdbException e) {
|
||||||
symbol = new BadMsSymbol(pdb, symbolTypeId);
|
symbol = new BadMsSymbol(pdb, symbolTypeId);
|
||||||
|
@ -64,14 +59,15 @@ public class SymbolParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsSymbol} from the {@link PdbByteReader} and returns it.
|
* 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 symbolTypeId the PDB ID for the symbol type to be parsed.
|
||||||
* @param reader {@link PdbByteReader} from which to deserialize the symbol record.
|
* @param reader {@link PdbByteReader} from which to deserialize the symbol record.
|
||||||
* @return {@link AbstractMsSymbol} that was parsed.
|
* @return {@link AbstractMsSymbol} that was parsed.
|
||||||
* @throws PdbException upon error parsing a field.
|
* @throws PdbException upon error parsing a field.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
private AbstractMsSymbol parseRecord(int symbolTypeId, PdbByteReader reader)
|
private static AbstractMsSymbol parseRecord(AbstractPdb pdb, int symbolTypeId,
|
||||||
throws PdbException, CancelledException {
|
PdbByteReader reader) throws PdbException, CancelledException {
|
||||||
|
|
||||||
pdb.getPdbReaderMetrics().witnessSymbolTypeId(symbolTypeId);
|
pdb.getPdbReaderMetrics().witnessSymbolTypeId(symbolTypeId);
|
||||||
|
|
||||||
|
|
|
@ -76,11 +76,19 @@ public class SymbolRecords {
|
||||||
int streamNumber;
|
int streamNumber;
|
||||||
PdbByteReader reader;
|
PdbByteReader reader;
|
||||||
|
|
||||||
streamNumber = pdb.getDebugInfo().getSymbolRecordsStreamNumber();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
if (debugInfo == null) {
|
||||||
symbolsByOffset = deserializeSymbolRecords(reader, monitor);
|
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();
|
streamNumber = module.getStreamNumberDebugInformation();
|
||||||
if (streamNumber != 0xffff) {
|
if (streamNumber != 0xffff) {
|
||||||
// System.out.println("\n\nStreamNumber: " + streamNumber);
|
// System.out.println("\n\nStreamNumber: " + streamNumber);
|
||||||
|
@ -90,7 +98,7 @@ public class SymbolRecords {
|
||||||
sizeDebug -= x; //TODO: seems right, but need to evaluate this
|
sizeDebug -= x; //TODO: seems right, but need to evaluate this
|
||||||
PdbByteReader debugReader = reader.getSubPdbByteReader(sizeDebug);
|
PdbByteReader debugReader = reader.getSubPdbByteReader(sizeDebug);
|
||||||
Map<Long, AbstractMsSymbol> oneModuleSymbolsByOffset =
|
Map<Long, AbstractMsSymbol> oneModuleSymbolsByOffset =
|
||||||
deserializeSymbolRecords(debugReader, monitor);
|
deserializeSymbolRecords(pdb, debugReader, monitor);
|
||||||
moduleSymbolsByOffset.add(oneModuleSymbolsByOffset);
|
moduleSymbolsByOffset.add(oneModuleSymbolsByOffset);
|
||||||
// TODO: figure out the rest of the bytes in the stream
|
// 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
|
// 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
|
* Deserializes the {@link AbstractMsSymbol} symbols from the {@link PdbByteReader} and
|
||||||
* returns a {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
* returns a {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
||||||
* symbols.
|
* symbols.
|
||||||
|
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
|
||||||
* @param reader {@link PdbByteReader} containing the symbol records to deserialize.
|
* @param reader {@link PdbByteReader} containing the symbol records to deserialize.
|
||||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||||
* @return map of buffer offsets to {@link AbstractMsSymbol symbols}.
|
* @return map of buffer offsets to {@link AbstractMsSymbol symbols}.
|
||||||
* @throws PdbException Upon not enough data left to parse.
|
* @throws PdbException Upon not enough data left to parse.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
public Map<Long, AbstractMsSymbol> deserializeSymbolRecords(PdbByteReader reader,
|
public static Map<Long, AbstractMsSymbol> deserializeSymbolRecords(AbstractPdb pdb,
|
||||||
TaskMonitor monitor) throws PdbException, CancelledException {
|
PdbByteReader reader, TaskMonitor monitor) throws PdbException, CancelledException {
|
||||||
|
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||||
//System.out.println(reader.dump(0x400));
|
//System.out.println(reader.dump(0x400));
|
||||||
SymbolParser parser = pdb.getSymbolParser();
|
|
||||||
Map<Long, AbstractMsSymbol> mySymbolsByOffset = new TreeMap<>();
|
Map<Long, AbstractMsSymbol> mySymbolsByOffset = new TreeMap<>();
|
||||||
while (reader.hasMore()) {
|
while (reader.hasMore()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
||||||
// Including length in byte array for alignment purposes.
|
// Including length in byte array for alignment purposes.
|
||||||
int offset = reader.getIndex();
|
int offset = reader.getIndex();
|
||||||
int recordLength = reader.parseUnsignedShortVal();
|
int recordLength = reader.parseUnsignedShortVal();
|
||||||
|
|
||||||
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
|
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
|
||||||
recordReader.markAlign(2);
|
recordReader.markAlign(2);
|
||||||
AbstractMsSymbol symbol = parser.parse(recordReader);
|
AbstractMsSymbol symbol = SymbolParser.parse(pdb, recordReader);
|
||||||
mySymbolsByOffset.put((long) offset, symbol);
|
mySymbolsByOffset.put((long) offset, symbol);
|
||||||
}
|
}
|
||||||
return mySymbolsByOffset;
|
return mySymbolsByOffset;
|
||||||
|
|
|
@ -26,34 +26,28 @@ import ghidra.util.exception.CancelledException;
|
||||||
*/
|
*/
|
||||||
public class TypeParser {
|
public class TypeParser {
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
// Internals
|
|
||||||
//==============================================================================================
|
|
||||||
protected AbstractPdb pdb;
|
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// API
|
// API
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed.
|
|
||||||
*/
|
*/
|
||||||
public TypeParser(AbstractPdb pdb) {
|
private TypeParser() {
|
||||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
|
||||||
this.pdb = pdb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
|
* 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 reader {@link PdbByteReader} from which to deserialize the data.
|
||||||
* @param recordNumber {@link RecordNumber} of the record.
|
* @param recordNumber {@link RecordNumber} of the record.
|
||||||
* @return {@link AbstractMsType} parsed.
|
* @return {@link AbstractMsType} parsed.
|
||||||
* @throws PdbException upon error parsing a field.
|
* @throws PdbException upon error parsing a field.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
public AbstractMsType parseRecord(PdbByteReader reader, RecordNumber recordNumber)
|
public static AbstractMsType parseRecord(AbstractPdb pdb, PdbByteReader reader,
|
||||||
throws PdbException, CancelledException {
|
RecordNumber recordNumber) throws PdbException, CancelledException {
|
||||||
AbstractMsType result = parse(reader, AbstractMsType.class);
|
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||||
|
AbstractMsType result = parse(pdb, reader, AbstractMsType.class);
|
||||||
result.setRecordNumber(recordNumber);
|
result.setRecordNumber(recordNumber);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -61,25 +55,29 @@ public class TypeParser {
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it
|
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it
|
||||||
* as a {@link MsTypeField}.
|
* 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.
|
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||||
* @return {@link MsTypeField} parsed.
|
* @return {@link MsTypeField} parsed.
|
||||||
* @throws PdbException upon error parsing a field.
|
* @throws PdbException upon error parsing a field.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
public MsTypeField parseField(PdbByteReader reader) throws PdbException, CancelledException {
|
public static MsTypeField parseField(AbstractPdb pdb, PdbByteReader reader)
|
||||||
MsTypeField result = parse(reader, MsTypeField.class);
|
throws PdbException, CancelledException {
|
||||||
|
MsTypeField result = parse(pdb, reader, MsTypeField.class);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
|
* 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 reader {@link PdbByteReader} from which to deserialize the data.
|
||||||
* @return {@link AbstractMsType} parsed.
|
* @return {@link AbstractMsType} parsed.
|
||||||
* @throws PdbException upon error parsing dataTypeId.
|
* @throws PdbException upon error parsing dataTypeId.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @throws CancelledException Upon user cancellation.
|
||||||
*/
|
*/
|
||||||
public AbstractMsType parse(PdbByteReader reader) throws PdbException, CancelledException {
|
public static AbstractMsType parse(AbstractPdb pdb, PdbByteReader reader)
|
||||||
AbstractMsType result = parse(reader, AbstractMsType.class);
|
throws PdbException, CancelledException {
|
||||||
|
AbstractMsType result = parse(pdb, reader, AbstractMsType.class);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,18 +87,19 @@ public class TypeParser {
|
||||||
* @param <T> the required type to be returned. IMPORTANT: T must only be one of:
|
* @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 AbstractMsType} or {@link MsTypeField} or something else in common with
|
||||||
* {@link BadMsType}, otherwise a Bad Cast Exception might occur.
|
* {@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 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
|
* @return an instance of type T or type T version of BadMsType. IMPORTANT: See restriction
|
||||||
* on T.
|
* on T.
|
||||||
* @throws PdbException upon error parsing dataTypeId.
|
* @throws PdbException upon error parsing dataTypeId.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @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 {
|
throws PdbException, CancelledException {
|
||||||
int dataTypeId = reader.parseUnsignedShortVal();
|
int dataTypeId = reader.parseUnsignedShortVal();
|
||||||
try {
|
try {
|
||||||
IdMsParsable parsable = parse(reader, dataTypeId);
|
IdMsParsable parsable = parse(pdb, reader, dataTypeId);
|
||||||
if (requiredClass.isInstance(parsable)) {
|
if (requiredClass.isInstance(parsable)) {
|
||||||
return requiredClass.cast(parsable);
|
return requiredClass.cast(parsable);
|
||||||
}
|
}
|
||||||
|
@ -114,13 +113,14 @@ public class TypeParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deserializes an {@link AbstractMsType} from the {@link PdbByteReader} and returns it.
|
* 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 reader {@link PdbByteReader} from which to deserialize the data.
|
||||||
* @param dataTypeId the PDB ID for the symbol type to be parsed.
|
* @param dataTypeId the PDB ID for the symbol type to be parsed.
|
||||||
* @return {@link AbstractMsType} parsed.
|
* @return {@link AbstractMsType} parsed.
|
||||||
* @throws PdbException upon error parsing a field.
|
* @throws PdbException upon error parsing a field.
|
||||||
* @throws CancelledException Upon user cancellation.
|
* @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 {
|
throws PdbException, CancelledException {
|
||||||
|
|
||||||
pdb.getPdbReaderMetrics().witnessDataTypeId(dataTypeId);
|
pdb.getPdbReaderMetrics().witnessDataTypeId(dataTypeId);
|
||||||
|
@ -418,7 +418,7 @@ public class TypeParser {
|
||||||
type = new ManagedStMsType(pdb, reader);
|
type = new ManagedStMsType(pdb, reader);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 0x1500 block
|
// 0x1500 block
|
||||||
case TypeServerMsType.PDB_ID:
|
case TypeServerMsType.PDB_ID:
|
||||||
type = new TypeServerMsType(pdb, reader);
|
type = new TypeServerMsType(pdb, reader);
|
||||||
break;
|
break;
|
||||||
|
@ -507,7 +507,7 @@ public class TypeParser {
|
||||||
type = new VirtualFunctionTableMsType(pdb, reader);
|
type = new VirtualFunctionTableMsType(pdb, reader);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 0x1600 block
|
// 0x1600 block
|
||||||
case FunctionIdMsType.PDB_ID:
|
case FunctionIdMsType.PDB_ID:
|
||||||
type = new FunctionIdMsType(pdb, reader);
|
type = new FunctionIdMsType(pdb, reader);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class DiscardedByLinkMsSymbol extends AbstractMsSymbol {
|
||||||
// SymbolParser parser = new SymbolParser(pdb);
|
// SymbolParser parser = new SymbolParser(pdb);
|
||||||
// symbolList = parser.deserializeSymbolRecords(dataReader);
|
// symbolList = parser.deserializeSymbolRecords(dataReader);
|
||||||
symbolList = getOrderedSymbols(
|
symbolList = getOrderedSymbols(
|
||||||
pdb.getSymbolRecords().deserializeSymbolRecords(dataReader, TaskMonitor.DUMMY));
|
SymbolRecords.deserializeSymbolRecords(pdb, dataReader, TaskMonitor.DUMMY));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,8 +51,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
|
||||||
throws PdbException, CancelledException {
|
throws PdbException, CancelledException {
|
||||||
super(pdb, reader);
|
super(pdb, reader);
|
||||||
while (reader.hasMore()) {
|
while (reader.hasMore()) {
|
||||||
MsTypeField type = pdb.getTypeParser().parseField(reader);
|
MsTypeField type = TypeParser.parseField(pdb, reader);
|
||||||
// AbstractMsType type = pdb.getTypeParser().parse(reader);
|
|
||||||
if ((type instanceof AbstractBaseClassMsType) ||
|
if ((type instanceof AbstractBaseClassMsType) ||
|
||||||
(type instanceof AbstractVirtualBaseClassMsType) ||
|
(type instanceof AbstractVirtualBaseClassMsType) ||
|
||||||
(type instanceof AbstractIndirectVirtualBaseClassMsType)) {
|
(type instanceof AbstractIndirectVirtualBaseClassMsType)) {
|
||||||
|
@ -85,7 +84,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of base class types.
|
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of base class types.
|
||||||
* @return List of base class types.
|
* @return List of base class types.
|
||||||
*/
|
*/
|
||||||
public List<MsTypeField> getBaseClassList() {
|
public List<MsTypeField> getBaseClassList() {
|
||||||
|
@ -94,7 +93,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of type members types of
|
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of type members types of
|
||||||
* this field list.
|
* this field list.
|
||||||
* @return Field list.
|
* @return Field list.
|
||||||
*/
|
*/
|
||||||
public List<MsTypeField> getMemberList() {
|
public List<MsTypeField> getMemberList() {
|
||||||
|
@ -103,7 +102,7 @@ public abstract class AbstractFieldListMsType extends AbstractMsType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> of other types. (We have
|
* Returns the (ordered?) {@link List}<{@link AbstractMsType}> 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.
|
* @return List of other types.
|
||||||
*/
|
*/
|
||||||
public List<MsTypeField> getMethodList() {
|
public List<MsTypeField> getMethodList() {
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class ReferencedSymbolMsType extends AbstractMsType {
|
||||||
super(pdb, reader);
|
super(pdb, reader);
|
||||||
int recordLength = reader.parseUnsignedShortVal();
|
int recordLength = reader.parseUnsignedShortVal();
|
||||||
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
|
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
|
||||||
symbolRecord = pdb.getSymbolParser().parse(recordReader);
|
symbolRecord = SymbolParser.parse(pdb, recordReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -327,10 +327,14 @@ public class PdbAddressManager {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private void determineMemoryBlocks() {
|
private void determineMemoryBlocks() {
|
||||||
PdbDebugInfo dbi = applicator.getPdb().getDebugInfo();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
segmentMapList = dbi.getSegmentMapList();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
if (dbi instanceof PdbNewDebugInfo) {
|
if (debugInfo == null) {
|
||||||
DebugData debugData = ((PdbNewDebugInfo) dbi).getDebugData();
|
return;
|
||||||
|
}
|
||||||
|
segmentMapList = debugInfo.getSegmentMapList();
|
||||||
|
if (debugInfo instanceof PdbNewDebugInfo) {
|
||||||
|
DebugData debugData = ((PdbNewDebugInfo) debugInfo).getDebugData();
|
||||||
imageSectionHeaders = debugData.getImageSectionHeadersOrig();
|
imageSectionHeaders = debugData.getImageSectionHeadersOrig();
|
||||||
if (imageSectionHeaders != null) {
|
if (imageSectionHeaders != null) {
|
||||||
omapFromSource = debugData.getOmapFromSource();
|
omapFromSource = debugData.getOmapFromSource();
|
||||||
|
@ -504,6 +508,10 @@ public class PdbAddressManager {
|
||||||
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
|
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
|
||||||
|
|
||||||
AbstractPdb pdb = applicator.getPdb();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Program program = applicator.getProgram();
|
Program program = applicator.getProgram();
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -511,7 +519,7 @@ public class PdbAddressManager {
|
||||||
|
|
||||||
Memory mem = program.getMemory();
|
Memory mem = program.getMemory();
|
||||||
MemoryBlock[] blocks = mem.getBlocks();
|
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}.
|
* 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.
|
@SuppressWarnings("unused") // for method not being called.
|
||||||
private boolean garnerSectionSegmentInformation() throws PdbException {
|
private boolean garnerSectionSegmentInformation() throws PdbException {
|
||||||
AbstractPdb pdb = applicator.getPdb();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
if (pdb.getDebugInfo() == null) {
|
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,10 +588,13 @@ public class PdbAddressManager {
|
||||||
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
|
// pdb.getDebugInfo().getDebugData().getImageSectionHeader();
|
||||||
|
|
||||||
int num = 1;
|
int num = 1;
|
||||||
for (AbstractModuleInformation module : pdb.getDebugInfo().getModuleInformationList()) {
|
for (AbstractModuleInformation module : debugInfo.getModuleInformationList()) {
|
||||||
if ("* Linker *".equals(module.getModuleName())) {
|
if ("* Linker *".equals(module.getModuleName())) {
|
||||||
List<AbstractMsSymbol> linkerSymbolList =
|
SymbolGroup symbolGroup = applicator.getSymbolGroupForModule(num);
|
||||||
applicator.getSymbolGroupForModule(num).getSymbols();
|
if (symbolGroup == null) {
|
||||||
|
continue; // should not happen
|
||||||
|
}
|
||||||
|
List<AbstractMsSymbol> linkerSymbolList = symbolGroup.getSymbols();
|
||||||
for (AbstractMsSymbol symbol : linkerSymbolList) {
|
for (AbstractMsSymbol symbol : linkerSymbolList) {
|
||||||
if (symbol instanceof PeCoffSectionMsSymbol) {
|
if (symbol instanceof PeCoffSectionMsSymbol) {
|
||||||
PeCoffSectionMsSymbol section = (PeCoffSectionMsSymbol) symbol;
|
PeCoffSectionMsSymbol section = (PeCoffSectionMsSymbol) symbol;
|
||||||
|
|
|
@ -377,12 +377,16 @@ public class PdbApplicator {
|
||||||
|
|
||||||
private List<SymbolGroup> createSymbolGroups() throws CancelledException, PdbException {
|
private List<SymbolGroup> createSymbolGroups() throws CancelledException, PdbException {
|
||||||
List<SymbolGroup> mySymbolGroups = new ArrayList<>();
|
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.
|
// moduleNumber zero is our global/public group.
|
||||||
for (int moduleNumber = 0; moduleNumber <= num; moduleNumber++) {
|
for (int moduleNumber = 0; moduleNumber <= num; moduleNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
Map<Long, AbstractMsSymbol> symbols =
|
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(moduleNumber);
|
||||||
pdb.getDebugInfo().getModuleSymbolsByOffset(moduleNumber);
|
|
||||||
SymbolGroup symbolGroup = new SymbolGroup(symbols, moduleNumber);
|
SymbolGroup symbolGroup = new SymbolGroup(symbols, moduleNumber);
|
||||||
mySymbolGroups.add(symbolGroup);
|
mySymbolGroups.add(symbolGroup);
|
||||||
}
|
}
|
||||||
|
@ -585,11 +589,16 @@ public class PdbApplicator {
|
||||||
throws CancelledException, PdbException {
|
throws CancelledException, PdbException {
|
||||||
|
|
||||||
List<String> categoryNames = new ArrayList<>();
|
List<String> categoryNames = new ArrayList<>();
|
||||||
int num = pdb.getDebugInfo().getNumModules();
|
|
||||||
for (int index = 1; index <= num; index++) {
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
monitor.checkCanceled();
|
if (debugInfo != null) {
|
||||||
String moduleName = pdb.getDebugInfo().getModuleInformation(index).getModuleName();
|
|
||||||
categoryNames.add(moduleName);
|
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("\\");
|
int index = pdbFilename.lastIndexOf("\\");
|
||||||
|
@ -655,7 +664,13 @@ public class PdbApplicator {
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
int findModuleNumberBySectionOffsetContribution(int section, long offset) throws PdbException {
|
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 sectionContributionOffset = sectionContribution.getOffset();
|
||||||
int maxSectionContributionOffset =
|
int maxSectionContributionOffset =
|
||||||
sectionContributionOffset + sectionContribution.getLength();
|
sectionContributionOffset + sectionContribution.getLength();
|
||||||
|
@ -675,8 +690,8 @@ public class PdbApplicator {
|
||||||
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
setMonitorMessage("PDB: Processing " + num + " data type components...");
|
setMonitorMessage("PDB: Processing " + num + " data type components...");
|
||||||
for (int indexNumber =
|
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
|
||||||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
//PdbResearch.checkBreak(indexNumber);
|
//PdbResearch.checkBreak(indexNumber);
|
||||||
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||||
|
@ -742,8 +757,8 @@ public class PdbApplicator {
|
||||||
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
|
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
setMonitorMessage("PDB: Processing " + num + " item type components...");
|
setMonitorMessage("PDB: Processing " + num + " item type components...");
|
||||||
for (int indexNumber =
|
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
|
||||||
ipi.getTypeIndexMin(); indexNumber < ipi.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
MsTypeApplier applier = getTypeApplier(RecordNumber.itemRecordNumber(indexNumber));
|
MsTypeApplier applier = getTypeApplier(RecordNumber.itemRecordNumber(indexNumber));
|
||||||
applier.apply();
|
applier.apply();
|
||||||
|
@ -785,8 +800,8 @@ public class PdbApplicator {
|
||||||
setMonitorMessage("PDB: Resolving " + num + " data type components...");
|
setMonitorMessage("PDB: Resolving " + num + " data type components...");
|
||||||
Date start = new Date();
|
Date start = new Date();
|
||||||
long longStart = start.getTime();
|
long longStart = start.getTime();
|
||||||
for (int indexNumber =
|
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
|
||||||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
//PdbResearch.checkBreak(indexNumber);
|
//PdbResearch.checkBreak(indexNumber);
|
||||||
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||||
|
@ -822,6 +837,9 @@ public class PdbApplicator {
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolGroup getSymbolGroupForModule(int moduleNumber) {
|
SymbolGroup getSymbolGroupForModule(int moduleNumber) {
|
||||||
|
if (moduleNumber < 0 || moduleNumber >= symbolGroups.size()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return symbolGroups.get(moduleNumber);
|
return symbolGroups.get(moduleNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,7 +1010,7 @@ public class PdbApplicator {
|
||||||
@SuppressWarnings("unused") // for method not being called.
|
@SuppressWarnings("unused") // for method not being called.
|
||||||
/**
|
/**
|
||||||
* Process all symbols. User should not then call other methods:
|
* Process all symbols. User should not then call other methods:
|
||||||
* {@link #processGlobalSymbols()}, (@link #processPublicSymbols()}, and
|
* {@link #processGlobalSymbolsNoTypedefs()}, (@link #processPublicSymbols()}, and
|
||||||
* {@link #processNonPublicOrGlobalSymbols()}.
|
* {@link #processNonPublicOrGlobalSymbols()}.
|
||||||
* @throws CancelledException upon user cancellation
|
* @throws CancelledException upon user cancellation
|
||||||
* @throws PdbException upon issue processing the request
|
* @throws PdbException upon issue processing the request
|
||||||
|
@ -1007,6 +1025,9 @@ public class PdbApplicator {
|
||||||
private void processMainSymbols() throws CancelledException, PdbException {
|
private void processMainSymbols() throws CancelledException, PdbException {
|
||||||
// Get a count
|
// Get a count
|
||||||
SymbolGroup symbolGroup = getSymbolGroup();
|
SymbolGroup symbolGroup = getSymbolGroup();
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int totalCount = symbolGroup.size();
|
int totalCount = symbolGroup.size();
|
||||||
setMonitorMessage("PDB: Applying " + totalCount + " main symbol components...");
|
setMonitorMessage("PDB: Applying " + totalCount + " main symbol components...");
|
||||||
monitor.initialize(totalCount);
|
monitor.initialize(totalCount);
|
||||||
|
@ -1016,11 +1037,19 @@ public class PdbApplicator {
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void processModuleSymbols() throws CancelledException {
|
private void processModuleSymbols() throws CancelledException {
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
int num = pdb.getDebugInfo().getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
|
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
|
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
continue; // should not happen
|
||||||
|
}
|
||||||
totalCount += symbolGroup.size();
|
totalCount += symbolGroup.size();
|
||||||
}
|
}
|
||||||
setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
|
setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
|
||||||
|
@ -1031,6 +1060,9 @@ public class PdbApplicator {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
// Process module symbols list
|
// Process module symbols list
|
||||||
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
|
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
continue; // should not happen
|
||||||
|
}
|
||||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||||
processSymbolGroup(moduleNumber, iter);
|
processSymbolGroup(moduleNumber, iter);
|
||||||
// catelogSymbols(index, symbolGroup);
|
// catelogSymbols(index, symbolGroup);
|
||||||
|
@ -1073,10 +1105,17 @@ public class PdbApplicator {
|
||||||
*/
|
*/
|
||||||
private void processPublicSymbols() throws CancelledException, PdbException {
|
private void processPublicSymbols() throws CancelledException, PdbException {
|
||||||
|
|
||||||
SymbolGroup symbolGroup = getSymbolGroup();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PublicSymbolInformation publicSymbolInformation =
|
SymbolGroup symbolGroup = getSymbolGroup();
|
||||||
pdb.getDebugInfo().getPublicSymbolInformation();
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||||
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
setMonitorMessage("PDB: Applying " + offsets.size() + " public symbol components...");
|
setMonitorMessage("PDB: Applying " + offsets.size() + " public symbol components...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
@ -1103,10 +1142,17 @@ public class PdbApplicator {
|
||||||
*/
|
*/
|
||||||
private void processGlobalSymbolsNoTypedefs() throws CancelledException, PdbException {
|
private void processGlobalSymbolsNoTypedefs() throws CancelledException, PdbException {
|
||||||
|
|
||||||
SymbolGroup symbolGroup = getSymbolGroup();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GlobalSymbolInformation globalSymbolInformation =
|
SymbolGroup symbolGroup = getSymbolGroup();
|
||||||
pdb.getDebugInfo().getGlobalSymbolInformation();
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
setMonitorMessage("PDB: Applying global symbols...");
|
setMonitorMessage("PDB: Applying global symbols...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
@ -1134,10 +1180,17 @@ public class PdbApplicator {
|
||||||
*/
|
*/
|
||||||
private void processGlobalTypdefSymbols() throws CancelledException, PdbException {
|
private void processGlobalTypdefSymbols() throws CancelledException, PdbException {
|
||||||
|
|
||||||
SymbolGroup symbolGroup = getSymbolGroup();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GlobalSymbolInformation globalSymbolInformation =
|
SymbolGroup symbolGroup = getSymbolGroup();
|
||||||
pdb.getDebugInfo().getGlobalSymbolInformation();
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
setMonitorMessage("PDB: Applying typedefs...");
|
setMonitorMessage("PDB: Applying typedefs...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
@ -1166,12 +1219,24 @@ public class PdbApplicator {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused") // for method not being called.
|
@SuppressWarnings("unused") // for method not being called.
|
||||||
private void processNonPublicOrGlobalSymbols() throws CancelledException, PdbException {
|
private void processNonPublicOrGlobalSymbols() throws CancelledException, PdbException {
|
||||||
Set<Long> offsetsRemaining = getSymbolGroup().getOffsets();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
for (long off : pdb.getDebugInfo().getPublicSymbolInformation().getModifiedHashRecordSymbolOffsets()) {
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolGroup symbolGroup = getSymbolGroup();
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Long> offsetsRemaining = symbolGroup.getOffsets();
|
||||||
|
for (long off : debugInfo.getPublicSymbolInformation()
|
||||||
|
.getModifiedHashRecordSymbolOffsets()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
offsetsRemaining.remove(off);
|
offsetsRemaining.remove(off);
|
||||||
}
|
}
|
||||||
for (long off : pdb.getDebugInfo().getGlobalSymbolInformation().getModifiedHashRecordSymbolOffsets()) {
|
for (long off : debugInfo.getGlobalSymbolInformation()
|
||||||
|
.getModifiedHashRecordSymbolOffsets()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
offsetsRemaining.remove(off);
|
offsetsRemaining.remove(off);
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1246,6 @@ public class PdbApplicator {
|
||||||
monitor.initialize(offsetsRemaining.size());
|
monitor.initialize(offsetsRemaining.size());
|
||||||
//getCategoryUtils().setModuleTypedefsCategory(null);
|
//getCategoryUtils().setModuleTypedefsCategory(null);
|
||||||
|
|
||||||
SymbolGroup symbolGroup = getSymbolGroup();
|
|
||||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||||
for (long offset : offsetsRemaining) {
|
for (long offset : offsetsRemaining) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
@ -1194,9 +1258,10 @@ public class PdbApplicator {
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private int findLinkerModuleNumber() {
|
private int findLinkerModuleNumber() {
|
||||||
if (pdb.getDebugInfo() != null) {
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo != null) {
|
||||||
int num = 1;
|
int num = 1;
|
||||||
for (AbstractModuleInformation module : pdb.getDebugInfo().getModuleInformationList()) {
|
for (AbstractModuleInformation module : debugInfo.getModuleInformationList()) {
|
||||||
if (isLinkerModule(module.getModuleName())) {
|
if (isLinkerModule(module.getModuleName())) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
@ -1242,16 +1307,24 @@ public class PdbApplicator {
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void processThunkSymbolsFromNonLinkerModules() throws CancelledException {
|
private void processThunkSymbolsFromNonLinkerModules() throws CancelledException {
|
||||||
|
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int linkerModuleNumber = findLinkerModuleNumber();
|
int linkerModuleNumber = findLinkerModuleNumber();
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
int num = pdb.getDebugInfo().getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
for (int index = 1; index <= num; index++) {
|
for (int index = 1; index <= num; index++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
if (index == linkerModuleNumber) {
|
if (index == linkerModuleNumber) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
|
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
continue; // should not happen
|
||||||
|
}
|
||||||
totalCount += symbolGroup.size();
|
totalCount += symbolGroup.size();
|
||||||
}
|
}
|
||||||
setMonitorMessage("PDB: Processing module thunks...");
|
setMonitorMessage("PDB: Processing module thunks...");
|
||||||
|
@ -1264,6 +1337,9 @@ public class PdbApplicator {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
|
SymbolGroup symbolGroup = getSymbolGroupForModule(index);
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
continue; // should not happen
|
||||||
|
}
|
||||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
|
|
|
@ -334,8 +334,8 @@ public class PdbResearch {
|
||||||
static void checkBreak(int recordNumber, MsTypeApplier applier) {
|
static void checkBreak(int recordNumber, MsTypeApplier applier) {
|
||||||
|
|
||||||
String nn = applier.getMsType().getName();
|
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(
|
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>"
|
||||||
nn)) {
|
.equals(nn)) {
|
||||||
doNothingSetBreakPointHere();
|
doNothingSetBreakPointHere();
|
||||||
}
|
}
|
||||||
if ("class std::__1::__iostream_category".equals(nn)) {
|
if ("class std::__1::__iostream_category".equals(nn)) {
|
||||||
|
@ -411,9 +411,18 @@ public class PdbResearch {
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
static void childWalk(PdbApplicator applicator, TaskMonitor monitor)
|
static void childWalk(PdbApplicator applicator, TaskMonitor monitor)
|
||||||
throws CancelledException, PdbException {
|
throws CancelledException, PdbException {
|
||||||
|
|
||||||
|
PdbDebugInfo debugInfo = applicator.getPdb().getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
||||||
GlobalSymbolInformation globalSymbolInformation =
|
if (symbolGroup == null) {
|
||||||
applicator.getPdb().getDebugInfo().getGlobalSymbolInformation();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
applicator.setMonitorMessage("PDB: Applying typedefs...");
|
applicator.setMonitorMessage("PDB: Applying typedefs...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
@ -449,6 +458,9 @@ public class PdbResearch {
|
||||||
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
|
ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier;
|
||||||
AbstractMsSymbolIterator refIter =
|
AbstractMsSymbolIterator refIter =
|
||||||
refSymbolApplier.getInitializedReferencedSymbolGroupIterator();
|
refSymbolApplier.getInitializedReferencedSymbolGroupIterator();
|
||||||
|
if (refIter == null) {
|
||||||
|
throw new PdbException("PDB: Referenced Symbol Error - not refIter");
|
||||||
|
}
|
||||||
// recursion
|
// recursion
|
||||||
childWalkSym(applicator, refIter.getModuleNumber(), refIter);
|
childWalkSym(applicator, refIter.getModuleNumber(), refIter);
|
||||||
}
|
}
|
||||||
|
@ -616,10 +628,18 @@ public class PdbResearch {
|
||||||
private static void processPublicSymbols(PdbApplicator applicator,
|
private static void processPublicSymbols(PdbApplicator applicator,
|
||||||
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
||||||
AbstractPdb pdb = applicator.getPdb();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
|
||||||
|
|
||||||
PublicSymbolInformation publicSymbolInformation =
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
pdb.getDebugInfo().getPublicSymbolInformation();
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||||
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
applicator.setMonitorMessage(
|
applicator.setMonitorMessage(
|
||||||
"PDB: Applying " + offsets.size() + " public symbol components...");
|
"PDB: Applying " + offsets.size() + " public symbol components...");
|
||||||
|
@ -643,10 +663,18 @@ public class PdbResearch {
|
||||||
private static void processGlobalSymbols(PdbApplicator applicator,
|
private static void processGlobalSymbols(PdbApplicator applicator,
|
||||||
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
||||||
AbstractPdb pdb = applicator.getPdb();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
|
||||||
|
|
||||||
GlobalSymbolInformation globalSymbolInformation =
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
pdb.getDebugInfo().getGlobalSymbolInformation();
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
||||||
|
if (symbolGroup == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
applicator.setMonitorMessage("PDB: Applying global symbols...");
|
applicator.setMonitorMessage("PDB: Applying global symbols...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
@ -669,8 +697,13 @@ public class PdbResearch {
|
||||||
private static void processModuleSymbols(PdbApplicator applicator,
|
private static void processModuleSymbols(PdbApplicator applicator,
|
||||||
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
Map<Address, List<Stuff>> map, TaskMonitor monitor) throws CancelledException {
|
||||||
AbstractPdb pdb = applicator.getPdb();
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
|
if (debugInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
int num = pdb.getDebugInfo().getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
|
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
SymbolGroup symbolGroup = applicator.getSymbolGroupForModule(moduleNumber);
|
SymbolGroup symbolGroup = applicator.getSymbolGroupForModule(moduleNumber);
|
||||||
|
@ -679,8 +712,8 @@ public class PdbResearch {
|
||||||
}
|
}
|
||||||
totalCount += symbolGroup.size();
|
totalCount += symbolGroup.size();
|
||||||
}
|
}
|
||||||
applicator.setMonitorMessage(
|
applicator
|
||||||
"PDB: Applying " + totalCount + " module symbol components...");
|
.setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
|
||||||
monitor.initialize(totalCount);
|
monitor.initialize(totalCount);
|
||||||
|
|
||||||
// Process symbols list for each module
|
// 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
|
// if count is zero for a definition, then, the field list record
|
||||||
// number refers to an actual field list.
|
// number refers to an actual field list.
|
||||||
// So... seems we can trust forward reference and ignore count.
|
// So... seems we can trust forward reference and ignore count.
|
||||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
if (compType
|
||||||
|
.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||||
doNothingSetBreakPointHere();
|
doNothingSetBreakPointHere();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,7 +946,8 @@ public class PdbResearch {
|
||||||
// the field list record number refers to an actual field
|
// the field list record number refers to an actual field
|
||||||
// list. So... seems we can trust forward reference and
|
// list. So... seems we can trust forward reference and
|
||||||
// ignore count.
|
// ignore count.
|
||||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
if (compType
|
||||||
|
.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||||
doNothingSetBreakPointHere();
|
doNothingSetBreakPointHere();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,20 @@ public class PdbVbtManager extends VbtManager {
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
TaskMonitor monitor = applicator.getMonitor();
|
TaskMonitor monitor = applicator.getMonitor();
|
||||||
SymbolGroup symbolGroup = applicator.getSymbolGroup();
|
|
||||||
Map<String, Address> myAddressByMangledName = new HashMap<>();
|
Map<String, Address> myAddressByMangledName = new HashMap<>();
|
||||||
|
|
||||||
PublicSymbolInformation publicSymbolInformation =
|
AbstractPdb pdb = applicator.getPdb();
|
||||||
applicator.getPdb().getDebugInfo().getPublicSymbolInformation();
|
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();
|
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
applicator.setMonitorMessage("PDB: Searching for virtual base table symbols...");
|
applicator.setMonitorMessage("PDB: Searching for virtual base table symbols...");
|
||||||
monitor.initialize(offsets.size());
|
monitor.initialize(offsets.size());
|
||||||
|
|
|
@ -53,11 +53,17 @@ public class ReferenceSymbolApplier extends MsSymbolApplier {
|
||||||
void apply() throws CancelledException, PdbException {
|
void apply() throws CancelledException, PdbException {
|
||||||
// Potential recursive call via applicator.procSym().
|
// Potential recursive call via applicator.procSym().
|
||||||
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator();
|
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator();
|
||||||
|
if (refIter == null) {
|
||||||
|
throw new PdbException("PDB: Referenced Symbol Error - null refIter");
|
||||||
|
}
|
||||||
applicator.procSym(refIter);
|
applicator.procSym(refIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() {
|
AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() {
|
||||||
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
|
SymbolGroup refSymbolGroup = getReferencedSymbolGroup();
|
||||||
|
if (refSymbolGroup == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
|
AbstractMsSymbolIterator refIter = refSymbolGroup.iterator();
|
||||||
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
|
refIter.initGetByOffset(getOffsetInReferencedSymbolGroup());
|
||||||
return refIter;
|
return refIter;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user