mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-2367 - PDB U - cleanup: remove Abstract from some names, incorporate filename and monitor into MSF and make available to PDB and other classes, better employ monitor in reader, fix some javadoc
This commit is contained in:
parent
6842712129
commit
e7846664a8
67 changed files with 1583 additions and 1559 deletions
|
@ -201,11 +201,10 @@ public class Pagedump extends DumpFile {
|
|||
applicatorOptions.setProcessingControl(PdbApplicatorControl.DATA_TYPES_ONLY);
|
||||
try (AbstractPdb pdb = PdbParser.parse(pdbFile.getPath(), readerOptions, monitor)) {
|
||||
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
||||
pdb.deserialize(monitor);
|
||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdbFile.getPath(), pdb);
|
||||
pdb.deserialize();
|
||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdb);
|
||||
applicator.applyTo(program, dtm, program.getImageBase(),
|
||||
applicatorOptions, monitor,
|
||||
(MessageLog) null);
|
||||
applicatorOptions, (MessageLog) null);
|
||||
}
|
||||
catch (PdbException | IOException | CancelledException e) {
|
||||
Msg.error(this, e.getMessage());
|
||||
|
|
|
@ -63,7 +63,7 @@ public class PdbDeveloperDumpScript extends GhidraScript {
|
|||
monitor.setMessage(message);
|
||||
Msg.info(this, message);
|
||||
try (AbstractPdb pdb = PdbParser.parse(pdbFileName, new PdbReaderOptions(), monitor)) {
|
||||
pdb.deserialize(monitor);
|
||||
pdb.deserialize();
|
||||
FileWriter fileWriter = new FileWriter(dumpFile);
|
||||
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
|
||||
outputHeaderMessage(bufferedWriter, pdbFileName);
|
||||
|
|
|
@ -86,7 +86,7 @@ public class PdbDeveloperDumpSetScript extends GhidraScript {
|
|||
println("Processing PDB Dump of: " + entry.input());
|
||||
try (AbstractPdb pdb =
|
||||
PdbParser.parse(entry.input(), new PdbReaderOptions(), monitor)) {
|
||||
pdb.deserialize(monitor);
|
||||
pdb.deserialize();
|
||||
try (BufferedWriter bufferedWriter =
|
||||
new BufferedWriter(new FileWriter(new File(entry.output())))) {
|
||||
outputHeaderMessage(bufferedWriter, entry.input());
|
||||
|
|
|
@ -61,7 +61,7 @@ public class PdbFactory {
|
|||
try {
|
||||
AbstractPdb pdb = PdbParser.parse(filename, new PdbReaderOptions(), monitor);
|
||||
PdbIdentifiers identifiers = pdb.getIdentifiers();
|
||||
pdb.deserialize(monitor);
|
||||
pdb.deserialize();
|
||||
PdbReaderMetrics metrics = pdb.getPdbReaderMetrics();
|
||||
pdbInfo = new PdbInfo(filename, identifiers, pdb, metrics);
|
||||
pdbInfoByFile.put(filename, pdbInfo);
|
||||
|
|
|
@ -41,7 +41,7 @@ public class PdbQuery {
|
|||
*/
|
||||
public static AbstractMsType getDataTypeRecord(GhidraScript script, AbstractPdb pdb,
|
||||
int number) {
|
||||
AbstractTypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
TypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
if (tpi == null) {
|
||||
println(script, "PDB does not contain a TPI... aborting search.");
|
||||
return null;
|
||||
|
@ -75,7 +75,7 @@ public class PdbQuery {
|
|||
*/
|
||||
public static AbstractMsType getItemTypeRecord(GhidraScript script, AbstractPdb pdb,
|
||||
int number) {
|
||||
AbstractTypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
TypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
if (ipi == null) {
|
||||
println(script, "PDB does not contain an IPI... aborting search.");
|
||||
return null;
|
||||
|
@ -102,7 +102,7 @@ public class PdbQuery {
|
|||
|
||||
/**
|
||||
* Searches PDB data type records that contain the search string. Outputs results to the
|
||||
* console.
|
||||
* console
|
||||
* @param script the script for which we are working
|
||||
* @param pdb the PDB to search
|
||||
* @param searchString the search string
|
||||
|
@ -110,7 +110,7 @@ public class PdbQuery {
|
|||
*/
|
||||
public static void searchDataTypes(GhidraScript script, AbstractPdb pdb, String searchString)
|
||||
throws CancelledException {
|
||||
AbstractTypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
TypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
if (tpi == null) {
|
||||
println(script, "PDB does not contain a TPI... aborting search.");
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ public class PdbQuery {
|
|||
|
||||
/**
|
||||
* Searches PDB item records that contain the search string. Outputs results to the
|
||||
* console.
|
||||
* console
|
||||
* @param script the script for which we are working
|
||||
* @param pdb the PDB to search
|
||||
* @param searchString the search string
|
||||
|
@ -148,7 +148,7 @@ public class PdbQuery {
|
|||
*/
|
||||
public static void searchItemTypes(GhidraScript script, AbstractPdb pdb, String searchString)
|
||||
throws CancelledException {
|
||||
AbstractTypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
TypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
if (ipi == null) {
|
||||
println(script, "PDB does not contain an IPI... aborting search.");
|
||||
return;
|
||||
|
@ -179,7 +179,7 @@ public class PdbQuery {
|
|||
|
||||
/**
|
||||
* Searches PDB symbol records that contain the search string. Outputs results to the
|
||||
* console.
|
||||
* console
|
||||
* @param script the script for which we are working
|
||||
* @param pdb the PDB to search
|
||||
* @param searchString the search string
|
||||
|
@ -238,7 +238,7 @@ public class PdbQuery {
|
|||
|
||||
/**
|
||||
* Method for outputting a message to the console (if script is not null); otherwise outputs
|
||||
* the message to Msg.info().
|
||||
* the message to Msg.info()
|
||||
* @param script the script
|
||||
* @param message the message to output to the console
|
||||
*/
|
||||
|
|
|
@ -180,10 +180,10 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
try (AbstractPdb pdb = PdbParser.parse(pdbFile.getPath(), pdbReaderOptions, monitor)) {
|
||||
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
||||
pdb.deserialize(monitor);
|
||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdbFile.getPath(), pdb);
|
||||
pdb.deserialize();
|
||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdb);
|
||||
applicator.applyTo(program, program.getDataTypeManager(), program.getImageBase(),
|
||||
pdbApplicatorOptions, monitor, log);
|
||||
pdbApplicatorOptions, log);
|
||||
|
||||
}
|
||||
catch (PdbException | IOException e) {
|
||||
|
@ -249,11 +249,11 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
|||
* on the specified program.
|
||||
* <p>
|
||||
* Normally the analyzer would locate the PDB file on its own, but if a
|
||||
* headless script wishes to override the analyzer's behaivor, it can
|
||||
* headless script wishes to override the analyzer's behavior, it can
|
||||
* use this method to specify a file.
|
||||
*
|
||||
* @param program {@link Program}
|
||||
* @param pdbFile the pdb file
|
||||
* @param program the program
|
||||
* @param pdbFile the PDB file
|
||||
*/
|
||||
public static void setPdbFileOption(Program program, File pdbFile) {
|
||||
PdbAnalyzerCommon.setPdbFileOption(NAME, program, pdbFile);
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.io.Writer;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.AbstractMsf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.MsfStream;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
|
@ -52,7 +52,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
//==============================================================================================
|
||||
// Internals
|
||||
//==============================================================================================
|
||||
protected AbstractMsf msf;
|
||||
protected Msf msf;
|
||||
|
||||
protected PdbReaderOptions readerOptions;
|
||||
|
||||
|
@ -63,7 +63,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
protected int pdbAge = 0;
|
||||
protected int dbiAge = 0;
|
||||
|
||||
protected AbstractTypeProgramInterface typeProgramInterface;
|
||||
protected TypeProgramInterface typeProgramInterface;
|
||||
protected PdbDebugInfo debugInfo;
|
||||
|
||||
protected Processor targetProcessor = Processor.UNKNOWN;
|
||||
|
@ -77,7 +77,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
protected List<Integer> parameters;
|
||||
protected NameTable nameTable;
|
||||
|
||||
protected AbstractTypeProgramInterface itemProgramInterface; //IPI seems to be a TPI.
|
||||
protected TypeProgramInterface itemProgramInterface; //IPI seems to be a TPI.
|
||||
|
||||
// Items below begin in Pdb700
|
||||
protected GUID guid; // We can return null by not initializing the guid.
|
||||
|
@ -104,10 +104,10 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Parses an address segment typically used by some {@link AbstractMsSymbol} type. In addition,
|
||||
* {@link PdbReaderMetrics} may be updated for segment information.
|
||||
* @param reader The reader from which to parse the segment.
|
||||
* @return The segment.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* {@link PdbReaderMetrics} may be updated for segment information
|
||||
* @param reader the reader from which to parse the segment
|
||||
* @return the segment
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public int parseSegment(PdbByteReader reader) throws PdbException {
|
||||
int segment = reader.parseUnsignedShortVal();
|
||||
|
@ -119,8 +119,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Closes the {@link AbstractPdb} and resources that it uses.
|
||||
* @throws IOException for file I/O reasons.
|
||||
* Closes the {@link AbstractPdb} and resources that it uses
|
||||
* @throws IOException for file I/O reasons
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
@ -130,26 +130,26 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PdbReaderOptions} for this PDB.
|
||||
* @return the {@link PdbReaderOptions} for this PDB.
|
||||
* Returns the {@link PdbReaderOptions} for this PDB
|
||||
* @return the {@link PdbReaderOptions} for this PDB
|
||||
*/
|
||||
public PdbReaderOptions getPdbReaderOptions() {
|
||||
return readerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* 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
|
||||
* @throws PdbException upon error in processing components
|
||||
*/
|
||||
public PdbIdentifiers getIdentifiers() throws IOException, PdbException {
|
||||
parseDBI();
|
||||
if (debugInfo != null) {
|
||||
try {
|
||||
// dbiAge and targetProcessor set during deserialization of new DBI header
|
||||
debugInfo.deserialize(true, TaskMonitor.DUMMY);
|
||||
debugInfo.deserialize(true);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
throw new AssertException(e); // unexpected
|
||||
|
@ -163,20 +163,19 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes this PDB from the underlying {@link AbstractMsf}.
|
||||
* @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.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes this PDB from the underlying {@link Msf}
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public void deserialize(TaskMonitor monitor)
|
||||
public void deserialize()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
// msf should only be null for testing versions of PDB.
|
||||
if (msf == null) {
|
||||
return;
|
||||
}
|
||||
deserializeDirectory(monitor);
|
||||
deserializeDirectory();
|
||||
|
||||
//directoryStream.dump(Integer.MAX_VALUE);
|
||||
//System.out.println(pdb.dumpDirectory());
|
||||
|
@ -186,7 +185,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
// pdb.dumpStream(3, 0x400);
|
||||
// pdb.dumpStream(4, 0x400);
|
||||
|
||||
deserializeSubstreams(monitor);
|
||||
deserializeSubstreams();
|
||||
// pdb.dumpSubStreams();
|
||||
|
||||
// pdb.dumpGlobalSymbols(); //TODO: evaluate where/who calls.
|
||||
|
@ -196,48 +195,48 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the Version Number of the PDB.
|
||||
* @return Version Number of the PDB.
|
||||
* Returns the Version Number of the PDB
|
||||
* @return Version Number of the PDB
|
||||
*/
|
||||
public int getVersionNumber() {
|
||||
return versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Signature of the PDB.
|
||||
* @return Signature of the PDB.
|
||||
* Returns the Signature of the PDB
|
||||
* @return Signature of the PDB
|
||||
*/
|
||||
public int getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Age of the PDB.
|
||||
* @return Age of the PDB.
|
||||
* Returns the Age of the PDB
|
||||
* @return Age of the PDB
|
||||
*/
|
||||
public int getAge() {
|
||||
return pdbAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GUID for the PDB.
|
||||
* @return {@link GUID} for the PDB.
|
||||
* Returns the GUID for the PDB
|
||||
* @return {@link GUID} for the PDB
|
||||
*/
|
||||
public GUID getGuid() {
|
||||
return guid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether the PDB file has been completely deserialized yet.
|
||||
* @return True if has been deserialized.
|
||||
* Tells whether the PDB file has been completely deserialized yet
|
||||
* @return {@code true} if has been deserialized
|
||||
*/
|
||||
public boolean isDeserialized() {
|
||||
return substreamsDeserialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index number of the target processor used for compilation.
|
||||
* @return Index number of the target processor used for compilation.
|
||||
* Get the index number of the target processor used for compilation
|
||||
* @return Index number of the target processor used for compilation
|
||||
* @see Processor
|
||||
* @see RegisterName
|
||||
*/
|
||||
|
@ -246,8 +245,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is minimal debug information.
|
||||
* @return {@code true} if there is minimal debug information.
|
||||
* Returns whether there is minimal debug information
|
||||
* @return {@code true} if there is minimal debug information
|
||||
*/
|
||||
public boolean hasMinimalDebugInfo() {
|
||||
return minimalDebugInfo;
|
||||
|
@ -275,7 +274,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Set the age as specified by the new DBI header. A value of 0 corresponds
|
||||
* to the old DBI header.
|
||||
* to the old DBI header
|
||||
* @param dbiAge age as specified by the new DBI header
|
||||
*/
|
||||
void setDbiAge(int dbiAge) {
|
||||
|
@ -283,26 +282,26 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractTypeProgramInterface} component.
|
||||
* @return {@link AbstractTypeProgramInterface} component or null if not available.
|
||||
* Returns the {@link TypeProgramInterface} component
|
||||
* @return {@link TypeProgramInterface} component or null if not available
|
||||
*/
|
||||
public AbstractTypeProgramInterface getTypeProgramInterface() {
|
||||
public TypeProgramInterface getTypeProgramInterface() {
|
||||
return typeProgramInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ItemProgramInterface (of type {@link AbstractTypeProgramInterface})
|
||||
* component.
|
||||
* @return ItemProgramInterface (of type {@link AbstractTypeProgramInterface}) component
|
||||
* or null if not available.
|
||||
* Returns the ItemProgramInterface (of type {@link TypeProgramInterface})
|
||||
* component
|
||||
* @return ItemProgramInterface (of type {@link TypeProgramInterface}) component
|
||||
* or null if not available
|
||||
*/
|
||||
public AbstractTypeProgramInterface getItemProgramInterface() {
|
||||
public TypeProgramInterface getItemProgramInterface() {
|
||||
return itemProgramInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PdbDebugInfo} component.
|
||||
* @return {@link PdbDebugInfo} component or null if not available.
|
||||
* Returns the {@link PdbDebugInfo} component
|
||||
* @return {@link PdbDebugInfo} component or null if not available
|
||||
*/
|
||||
public PdbDebugInfo getDebugInfo() {
|
||||
return debugInfo;
|
||||
|
@ -311,8 +310,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
/**
|
||||
* Returns the record for the associated record number, which is expected to match the
|
||||
* desired class
|
||||
* @param recordNumber the record number.
|
||||
* @return the record.
|
||||
* @param recordNumber the record number
|
||||
* @return the record
|
||||
*/
|
||||
public AbstractMsType getTypeRecord(RecordNumber recordNumber) {
|
||||
return getTypeRecord(recordNumber, AbstractMsType.class);
|
||||
|
@ -320,11 +319,11 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Returns the record for the associated record number, which is expected to match the
|
||||
* desired class.
|
||||
* @param <T> class return type.
|
||||
* @param recordNumber record number.
|
||||
* @param typeClass desired class type for return.
|
||||
* @return the record.
|
||||
* desired class
|
||||
* @param <T> class return type
|
||||
* @param recordNumber record number
|
||||
* @param typeClass desired class type for return
|
||||
* @return the record
|
||||
*/
|
||||
public <T extends AbstractMsType> T getTypeRecord(RecordNumber recordNumber,
|
||||
Class<T> typeClass) {
|
||||
|
@ -369,18 +368,18 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a name from the {@link NameTable} pertaining to the index argument.
|
||||
* @param index Index of the name.
|
||||
* @return Name.
|
||||
* Returns a name from the {@link NameTable} pertaining to the index argument
|
||||
* @param index index of the name
|
||||
* @return name
|
||||
*/
|
||||
public String getNameFromNameIndex(int index) {
|
||||
return nameTable.getNameFromStreamNumber(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index of the {@link String} name argument in the {@link NameTable}.
|
||||
* @param name Name for which to find the index.
|
||||
* @return Index of the name argument.
|
||||
* Returns an index of the {@link String} name argument in the {@link NameTable}
|
||||
* @param name name for which to find the index
|
||||
* @return index of the name argument
|
||||
*/
|
||||
public int getNameIndexFromName(String name) {
|
||||
return nameTable.getStreamNumberFromName(name);
|
||||
|
@ -388,9 +387,9 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Returns a name from the {@link NameTable} pertaining to the byte-offset in the block of
|
||||
* names for the table.
|
||||
* @param offset Byte-offset of the name in the {@link NameTable} block.
|
||||
* @return Name at the byte offset in the Name Table.
|
||||
* names for the table
|
||||
* @param offset byte offset of the name in the {@link NameTable} block
|
||||
* @return name at the byte offset in the Name Table
|
||||
*/
|
||||
public String getNameStringFromOffset(int offset) {
|
||||
return nameTable.getNameStringFromOffset(offset);
|
||||
|
@ -400,43 +399,42 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the number of bytes needed to store a PDB version number.
|
||||
* location.
|
||||
* @return Number of bytes needed to store a PDV version number.
|
||||
* Returns the number of bytes needed to store a PDB version number
|
||||
* @return number of bytes needed to store a PDV version number
|
||||
*/
|
||||
static int getVersionNumberSize() {
|
||||
return VERSION_NUMBER_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes PDB Version Number from the PDB Directory Stream in the {@link AbstractMsf}.
|
||||
* @param msf {@link AbstractMsf} underlying the PDB of which to probe.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return Version number.
|
||||
* @throws IOException on file I/O issues.
|
||||
* @throws PdbException on parsing issues.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes PDB Version Number from the PDB Directory Stream in the {@link Msf}
|
||||
* @param msf {@link Msf} underlying the PDB of which to probe
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation
|
||||
* @return version number
|
||||
* @throws IOException on file I/O issues
|
||||
* @throws PdbException on parsing issues
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
static int deserializeVersionNumber(AbstractMsf msf, TaskMonitor monitor)
|
||||
static int deserializeVersionNumber(Msf msf, TaskMonitor monitor)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
|
||||
MsfStream directoryStream = msf.getStream(PDB_DIRECTORY_STREAM_NUMBER);
|
||||
if (directoryStream.getLength() < AbstractPdb.getVersionNumberSize()) {
|
||||
throw new PdbException("Directory Stream too short");
|
||||
}
|
||||
byte[] bytes = directoryStream.read(0, AbstractPdb.getVersionNumberSize(), monitor);
|
||||
byte[] bytes = directoryStream.read(0, AbstractPdb.getVersionNumberSize());
|
||||
PdbByteReader pdbDirectoryReader = new PdbByteReader(bytes);
|
||||
return pdbDirectoryReader.parseInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf {@link AbstractMsf} foundation for the PDB.
|
||||
* @param readerOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration or error in processing components.
|
||||
* Constructor
|
||||
* @param msf {@link Msf} foundation for the PDB
|
||||
* @param readerOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration or error in processing components
|
||||
*/
|
||||
AbstractPdb(AbstractMsf msf, PdbReaderOptions readerOptions) throws IOException, PdbException {
|
||||
AbstractPdb(Msf msf, PdbReaderOptions readerOptions) throws IOException, PdbException {
|
||||
this.msf = msf;
|
||||
this.readerOptions = readerOptions;
|
||||
strings = new ArrayList<>();
|
||||
|
@ -446,34 +444,57 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Deserializes the main {@link PdbIdentifiers} found in the PDB Directory from the
|
||||
* {@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.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* {@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
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
abstract void deserializeIdentifiersOnly(TaskMonitor monitor)
|
||||
throws IOException, PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractMsf} foundation for the PDB.
|
||||
* @return {@link AbstractMsf} foundation of the PDB.
|
||||
* Returns the filename
|
||||
* @return the filename
|
||||
*/
|
||||
AbstractMsf getMsf() {
|
||||
public String getFilename() {
|
||||
return msf.getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TaskMonitor
|
||||
* @return the monitor
|
||||
*/
|
||||
public TaskMonitor getMonitor() {
|
||||
return msf.getMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this monitor has been canceled
|
||||
* @throws CancelledException if monitor has been cancelled
|
||||
*/
|
||||
public void checkCanceled() throws CancelledException {
|
||||
getMonitor().checkCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Msf} foundation for the PDB
|
||||
* @return {@link Msf} foundation of the PDB
|
||||
*/
|
||||
Msf getMsf() {
|
||||
return msf;
|
||||
}
|
||||
|
||||
//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.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the sub-streams for this {@link AbstractPdb} object
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializeSubstreams(TaskMonitor monitor)
|
||||
void deserializeSubstreams()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
|
||||
if (substreamsDeserialized) {
|
||||
|
@ -482,18 +503,18 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
TypeProgramInterfaceParser tpiParser = new TypeProgramInterfaceParser();
|
||||
|
||||
typeProgramInterface = tpiParser.parse(this, monitor);
|
||||
typeProgramInterface = tpiParser.parse(this);
|
||||
if (typeProgramInterface != null) {
|
||||
typeProgramInterface.deserialize(monitor);
|
||||
typeProgramInterface.deserialize();
|
||||
}
|
||||
|
||||
boolean ipiStreamHasNoName = ItemProgramInterfaceParser.hackCheckNoNameForStream(nameTable);
|
||||
pdbReaderMetrics.witnessIpiDetection(ipiStreamHasNoName, hasIdStream);
|
||||
if (hasIdStream || ipiStreamHasNoName) {
|
||||
ItemProgramInterfaceParser ipiParser = new ItemProgramInterfaceParser();
|
||||
itemProgramInterface = ipiParser.parse(this, monitor);
|
||||
itemProgramInterface = ipiParser.parse(this);
|
||||
if (itemProgramInterface != null) {
|
||||
itemProgramInterface.deserialize(monitor);
|
||||
itemProgramInterface.deserialize();
|
||||
}
|
||||
//processDependencyIndexPairList();
|
||||
//dumpDependencyGraph();
|
||||
|
@ -501,7 +522,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
parseDBI();
|
||||
if (debugInfo != null) {
|
||||
debugInfo.deserialize(false, monitor);
|
||||
debugInfo.deserialize(false);
|
||||
}
|
||||
|
||||
substreamsDeserialized = true;
|
||||
|
@ -517,47 +538,45 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Returns a {@link PdbByteReader} initialized with the complete contents of the
|
||||
* {@link MsfStream} referenced by {@code streamNumber}.
|
||||
* @param streamNumber The stream number of the {@link MsfStream} from which to load the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return The {@link PdbByteReader}.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* {@link MsfStream} referenced by {@code streamNumber}
|
||||
* @param streamNumber the stream number of the {@link MsfStream} from which to load the data
|
||||
* @return the {@link PdbByteReader}
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
PdbByteReader getReaderForStreamNumber(int streamNumber, TaskMonitor monitor)
|
||||
PdbByteReader getReaderForStreamNumber(int streamNumber)
|
||||
throws IOException, CancelledException {
|
||||
return getReaderForStreamNumber(streamNumber, 0, MsfStream.MAX_STREAM_LENGTH, monitor);
|
||||
return getReaderForStreamNumber(streamNumber, 0, MsfStream.MAX_STREAM_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link PdbByteReader} initialized with up to {@code numToRead} byte of content
|
||||
* (less if not available) from the {@link MsfStream} referenced by {@code streamNumber}
|
||||
* starting at {@code streamOffset}.
|
||||
* @param streamNumber The stream number of the {@link MsfStream} from which to load the data.
|
||||
* @param streamOffset Starting location within the {@link MsfStream} from which to get the
|
||||
* data.
|
||||
* @param numToRead Number of bytes used to initialize the {@link PdbByteReader}.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return The {@link PdbByteReader}.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* starting at {@code streamOffset}
|
||||
* @param streamNumber the stream number of the {@link MsfStream} from which to load the data
|
||||
* @param streamOffset starting location within the {@link MsfStream} from which to get the
|
||||
* data
|
||||
* @param numToRead number of bytes used to initialize the {@link PdbByteReader}
|
||||
* @return the {@link PdbByteReader}
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
PdbByteReader getReaderForStreamNumber(int streamNumber, int streamOffset, int numToRead,
|
||||
TaskMonitor monitor) throws IOException, CancelledException {
|
||||
PdbByteReader getReaderForStreamNumber(int streamNumber, int streamOffset, int numToRead)
|
||||
throws IOException, CancelledException {
|
||||
MsfStream stream = msf.getStream(streamNumber);
|
||||
numToRead = Math.min(numToRead, stream.getLength() - streamOffset);
|
||||
byte[] bytes = stream.read(streamOffset, numToRead, monitor);
|
||||
byte[] bytes = stream.read(streamOffset, numToRead);
|
||||
PdbByteReader reader = new PdbByteReader(bytes);
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method to dump the number of bytes for the specified stream to a {@link String}.
|
||||
* @param streamNumber The stream number to dump.
|
||||
* @param maxOut The maximum number of bytes to dump.
|
||||
* @return {@link String} of pretty output.
|
||||
* Debug method to dump the number of bytes for the specified stream to a {@link String}
|
||||
* @param streamNumber the stream number to dump
|
||||
* @param maxOut the maximum number of bytes to dump
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
String dumpStream(int streamNumber, int maxOut) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -569,21 +588,20 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes PDB Directory from the {@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.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes PDB Directory from the {@link PdbByteReader}
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
abstract void deserializeDirectory(TaskMonitor monitor)
|
||||
abstract void deserializeDirectory()
|
||||
throws IOException, PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Dumps the PDB Directory to {@link Writer}. This package-protected method is for
|
||||
* debugging only.
|
||||
* @param writer {@link Writer}.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* @throws IOException on issue writing to the {@link Writer}.
|
||||
*/
|
||||
public abstract void dumpDirectory(Writer writer) throws IOException;
|
||||
|
||||
|
@ -592,23 +610,22 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
//==============================================================================================
|
||||
|
||||
/**
|
||||
* Reads the Directory stream and returns a {@link PdbByteReader} of its contents.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return {@link PdbByteReader} requested.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Reads the Directory stream and returns a {@link PdbByteReader} of its contents
|
||||
* @return {@link PdbByteReader} requested
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected PdbByteReader getDirectoryReader(TaskMonitor monitor)
|
||||
protected PdbByteReader getDirectoryReader()
|
||||
throws IOException, CancelledException {
|
||||
return getReaderForStreamNumber(PDB_DIRECTORY_STREAM_NUMBER, 0, MsfStream.MAX_STREAM_LENGTH,
|
||||
monitor);
|
||||
return getReaderForStreamNumber(PDB_DIRECTORY_STREAM_NUMBER, 0,
|
||||
MsfStream.MAX_STREAM_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the Version, Signature, and Age.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the Version, Signature, and Age
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected void deserializeVersionSignatureAge(PdbByteReader reader) throws PdbException {
|
||||
versionNumber = reader.parseInt();
|
||||
|
@ -617,8 +634,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps the Version Signature and Age. This package-protected method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the Version Signature and Age. This package-protected method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
protected String dumpVersionSignatureAge() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -633,26 +650,25 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes the Parameters.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @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.
|
||||
* @throws PdbException upon error parsing a string.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Parameters
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a string
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void deserializeParameters(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected void deserializeParameters(PdbByteReader reader)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
nameTable.deserializeDirectory(reader, monitor);
|
||||
nameTable.deserializeDirectory(reader);
|
||||
// Read the parameters.
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
getMonitor().checkCanceled();
|
||||
int val = reader.parseInt();
|
||||
parameters.add(val);
|
||||
}
|
||||
// Check the parameters for IDs
|
||||
for (int param : parameters) {
|
||||
monitor.checkCanceled();
|
||||
getMonitor().checkCanceled();
|
||||
if (param == MINIMAL_DEBUG_INFO_PARAM) {
|
||||
minimalDebugInfo = true;
|
||||
}
|
||||
|
@ -670,8 +686,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Dumps the Parameters to a {@link String}. This package-protected method is for
|
||||
* debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
protected String dumpParameters() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -694,11 +710,11 @@ public abstract class AbstractPdb implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Dumps the Sub-Streams to a {@link Writer}. This package-protected method is for
|
||||
* debugging only.
|
||||
* @param writer {@link Writer}.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* debugging only
|
||||
* @param writer {@link Writer}
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public void dumpSubStreams(Writer writer) throws IOException, CancelledException, PdbException {
|
||||
writer.write("SubStreams--------------------------------------------------\n");
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.*;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents Global Symbol Information or Public Symbol Information component of a
|
||||
|
@ -62,16 +61,16 @@ public abstract class AbstractSymbolInformation {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdbIn {@link AbstractPdb} that owns the Abstract Symbol Information to process.
|
||||
* Constructor
|
||||
* @param pdbIn {@link AbstractPdb} that owns the Abstract Symbol Information to process
|
||||
*/
|
||||
public AbstractSymbolInformation(AbstractPdb pdbIn) {
|
||||
pdb = pdbIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of symbols for this {@link AbstractSymbolInformation}.
|
||||
* @return the symbols.
|
||||
* Returns the list of symbols for this {@link AbstractSymbolInformation}
|
||||
* @return the symbols
|
||||
*/
|
||||
public List<AbstractMsSymbol> getSymbols() {
|
||||
return symbols;
|
||||
|
@ -79,7 +78,7 @@ public abstract class AbstractSymbolInformation {
|
|||
|
||||
/**
|
||||
* Returns the Offsets of symbols within the symbol table; these are gotten from the
|
||||
* HashRecords and modified to point to the size field of the symbols in the symbol table.
|
||||
* HashRecords and modified to point to the size field of the symbols in the symbol table
|
||||
* @return offsets
|
||||
*/
|
||||
public List<Long> getModifiedHashRecordSymbolOffsets() {
|
||||
|
@ -90,15 +89,14 @@ public abstract class AbstractSymbolInformation {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserialize the {@link AbstractSymbolInformation} from the appropriate stream in the Pdb.
|
||||
* @param streamNumber the stream number containing the information to deserialize.
|
||||
* @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.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserialize the {@link AbstractSymbolInformation} from the appropriate stream in the Pdb
|
||||
* @param streamNumber the stream number containing the information to deserialize
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserialize(int streamNumber, TaskMonitor monitor)
|
||||
void deserialize(int streamNumber)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
if (pdb.hasMinimalDebugInfo()) {
|
||||
hashRecordsBitMapLength = 0x8000;
|
||||
|
@ -113,11 +111,12 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping information from this {@link AbstractSymbolInformation}.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* Debug method for dumping information from this {@link AbstractSymbolInformation}
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void dump(Writer writer) throws IOException {
|
||||
void dump(Writer writer) throws IOException, CancelledException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("AbstractSymbolInformation-----------------------------------\n");
|
||||
dumpHashHeader(builder);
|
||||
|
@ -128,8 +127,8 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping basic information from this {@link AbstractSymbolInformation}.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping basic information from this {@link AbstractSymbolInformation}
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
*/
|
||||
protected void dumpHashBasics(StringBuilder builder) {
|
||||
builder.append("HashBasics--------------------------------------------------\n");
|
||||
|
@ -143,8 +142,8 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping information from this {@link AbstractSymbolInformation} header.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping information from this {@link AbstractSymbolInformation} header
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
*/
|
||||
protected void dumpHashHeader(StringBuilder builder) {
|
||||
builder.append("HashHeader--------------------------------------------------\n");
|
||||
|
@ -160,12 +159,11 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a list of symbols from the information that we have.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon PDB corruption.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Generates a list of symbols from the information that we have
|
||||
* @throws PdbException upon PDB corruption
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void generateSymbolsList(TaskMonitor monitor)
|
||||
protected void generateSymbolsList()
|
||||
throws PdbException, CancelledException {
|
||||
symbols = new ArrayList<>();
|
||||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||
|
@ -174,7 +172,7 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
Map<Long, AbstractMsSymbol> symbolsByOffset = debugInfo.getSymbolsByOffset();
|
||||
for (SymbolHashRecord record : hashRecords) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
long offset = record.getOffset() - 2; // Modified offset
|
||||
AbstractMsSymbol symbol = symbolsByOffset.get(offset);
|
||||
modifiedHashRecordSymbolOffsets.add(offset);
|
||||
|
@ -186,13 +184,15 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping hash records from this {@link AbstractSymbolInformation}.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping hash records from this {@link AbstractSymbolInformation}
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dumpHashRecords(StringBuilder builder) {
|
||||
protected void dumpHashRecords(StringBuilder builder) throws CancelledException {
|
||||
builder.append("HashRecords-------------------------------------------------\n");
|
||||
builder.append("numHashRecords: " + hashRecords.size() + "\n");
|
||||
for (SymbolHashRecord record : hashRecords) {
|
||||
pdb.checkCanceled();
|
||||
builder.append(
|
||||
String.format("0X%08X 0X%04X\n", record.getOffset(), record.getReferenceCount()));
|
||||
}
|
||||
|
@ -200,13 +200,12 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes the hash table for the symbols.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the hash table for the symbols
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void deserializeHashTable(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected void deserializeHashTable(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
|
||||
deserializeHashHeader(reader);
|
||||
|
@ -214,7 +213,7 @@ public abstract class AbstractSymbolInformation {
|
|||
if (headerSignature == HEADER_SIGNATURE) {
|
||||
switch (versionNumber) {
|
||||
case GSI70:
|
||||
deserializeGsi70HashTable(reader, monitor);
|
||||
deserializeGsi70HashTable(reader);
|
||||
break;
|
||||
default:
|
||||
throw new PdbException("Unknown GSI Version Number");
|
||||
|
@ -222,15 +221,15 @@ public abstract class AbstractSymbolInformation {
|
|||
}
|
||||
else {
|
||||
reader.reset(); // There was no header
|
||||
deserializeGsiPre70HashTable(reader, monitor);
|
||||
deserializeGsiPre70HashTable(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize the header of the Hash from the {@link PdbByteReader} provided.
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserialize the header of the Hash from the {@link PdbByteReader} provided
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
private void deserializeHashHeader(PdbByteReader reader) throws PdbException {
|
||||
headerSignature = reader.parseInt();
|
||||
|
@ -241,13 +240,12 @@ public abstract class AbstractSymbolInformation {
|
|||
|
||||
/**
|
||||
* Deserialize the body of the {@link AbstractSymbolInformation} according to the GSI versions
|
||||
* prior to 7.00 specification.
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon unexpected fields.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* prior to 7.00 specification
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon unexpected fields
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeGsiPre70HashTable(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeGsiPre70HashTable(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
|
||||
int numBucketsBytes = 4 * (numHashRecords + 1);
|
||||
|
@ -264,7 +262,7 @@ public abstract class AbstractSymbolInformation {
|
|||
|
||||
hashBucketOffsets = new ArrayList<>();
|
||||
while (bucketsReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
hashBucketOffsets.add(bucketsReader.parseInt());
|
||||
}
|
||||
|
||||
|
@ -273,18 +271,17 @@ public abstract class AbstractSymbolInformation {
|
|||
// take the offset and multiple by 2/3 to get the byte offset into the reader for the
|
||||
// actual record. Still need to deal with the collision logic after that.
|
||||
|
||||
deserializeHashRecords(hashRecordsReader, monitor);
|
||||
deserializeHashRecords(hashRecordsReader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize the body of the {@link AbstractSymbolInformation} according to the GSI 7.00
|
||||
* specification.
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon unexpected fields.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* specification
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon unexpected fields
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeGsi70HashTable(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeGsi70HashTable(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
|
||||
if (reader.numRemaining() != hashRecordsLength + bucketsLength) {
|
||||
|
@ -297,7 +294,7 @@ public abstract class AbstractSymbolInformation {
|
|||
PdbByteReader hashRecordsReader = reader.getSubPdbByteReader(hashRecordsLength);
|
||||
PdbByteReader bucketsReader = reader.getSubPdbByteReader(bucketsLength);
|
||||
|
||||
deserializedCompressedHashBuckets(bucketsReader, monitor);
|
||||
deserializedCompressedHashBuckets(bucketsReader);
|
||||
|
||||
// int i = 0;
|
||||
// for (int x : hashBucketOffsets) {
|
||||
|
@ -308,30 +305,29 @@ public abstract class AbstractSymbolInformation {
|
|||
// take the offset and multiple by 2/3 to get the byte offset into the reader for the
|
||||
// actual record. Still need to deal with the collision logic after that.
|
||||
|
||||
deserializeHashRecords(hashRecordsReader, monitor);
|
||||
deserializeHashRecords(hashRecordsReader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a compressed set of hash buckets from the {@link PdbByteReader} provided. The
|
||||
* data comes as a bit-mapped representation of which indices should contain the data followed
|
||||
* by a flat set of hash buckets that will be set at those indices in the order provided.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* by a flat set of hash buckets that will be set at those indices in the order provided
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializedCompressedHashBuckets(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializedCompressedHashBuckets(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
|
||||
PdbByteReader bitEncoderReader = reader.getSubPdbByteReader(hashRecordsBitMapLength);
|
||||
// Throw away extra bytes between bit map and buckets.
|
||||
reader.getSubPdbByteReader(numExtraBytes);
|
||||
while (bitEncoderReader.hasMore() && reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
long val = bitEncoderReader.parseUnsignedIntVal();
|
||||
//bitEncoded[index++] = val;
|
||||
for (int bit = 0; bit < 32 && reader.hasMore(); bit++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
if ((val & 0x01L) == 0x01L) {
|
||||
hashBucketOffsets.add(reader.parseInt());
|
||||
}
|
||||
|
@ -348,7 +344,7 @@ public abstract class AbstractSymbolInformation {
|
|||
throw new PdbException("Compressed GSI Hash Buckets corrupt");
|
||||
}
|
||||
while (bitEncoderReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
if (bitEncoderReader.parseUnsignedIntVal() != 0) {
|
||||
throw new PdbException("Compressed GSI Hash Buckets corrupt");
|
||||
}
|
||||
|
@ -357,17 +353,16 @@ 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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the hash records
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeHashRecords(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeHashRecords(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
hashRecords = new TreeSet<>();
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
SymbolHashRecord record = new SymbolHashRecord();
|
||||
record.parse(reader);
|
||||
hashRecords.add(record);
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* C11Lines information. As best as we know, only one of C11Lines or C13Lines can be found after
|
||||
|
@ -48,12 +47,12 @@ public class C11Lines {
|
|||
private List<List<List<Long>>> offsets; // unsigned int
|
||||
private List<List<List<Integer>>> lineNumbers; // unsigned short
|
||||
|
||||
public static C11Lines parse(AbstractPdb pdb, PdbByteReader reader, TaskMonitor monitor)
|
||||
public static C11Lines parse(AbstractPdb pdb, PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
return new C11Lines(pdb, reader, monitor);
|
||||
return new C11Lines(pdb, reader);
|
||||
}
|
||||
|
||||
private C11Lines(AbstractPdb pdb, PdbByteReader reader, TaskMonitor monitor)
|
||||
private C11Lines(AbstractPdb pdb, PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
if (reader.numRemaining() < 4) {
|
||||
return;
|
||||
|
@ -64,7 +63,7 @@ public class C11Lines {
|
|||
startEnd = new ArrayList<>();
|
||||
seg = new ArrayList<>();
|
||||
for (int i = 0; i < cFile; i++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int val = reader.parseInt();
|
||||
if (val < 0) {
|
||||
throw new PdbException("beyond our max integer limitation");
|
||||
|
@ -72,13 +71,13 @@ public class C11Lines {
|
|||
baseSrcFile.add(val);
|
||||
}
|
||||
for (int i = 0; i < cSeg; i++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
StartEnd se = new StartEnd();
|
||||
se.parse(reader);
|
||||
startEnd.add(se);
|
||||
}
|
||||
for (int i = 0; i < cSeg; i++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
seg.add(reader.parseUnsignedShortVal());
|
||||
}
|
||||
ccSegs = new ArrayList<>();
|
||||
|
@ -89,14 +88,14 @@ public class C11Lines {
|
|||
offsets = new ArrayList<>();
|
||||
lineNumbers = new ArrayList<>();
|
||||
for (int i = 0; i < cFile; i++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
reader.setIndex(baseSrcFile.get(i));
|
||||
int ccSeg = reader.parseUnsignedShortVal();
|
||||
ccSegs.add(ccSeg);
|
||||
reader.skip(2); // padding
|
||||
List<Integer> baseSrcLn = new ArrayList<>();
|
||||
for (int j = 0; j < ccSeg; j++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
baseSrcLn.add(reader.parseInt());
|
||||
}
|
||||
baseSrcLines.add(baseSrcLn);
|
||||
|
@ -113,20 +112,20 @@ public class C11Lines {
|
|||
List<List<Long>> fileSegOffsets = new ArrayList<>(); // unsigned int
|
||||
List<List<Integer>> fileSegLineNums = new ArrayList<>(); // unsigned short
|
||||
for (int j = 0; j < ccSeg; j++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
reader.setIndex(baseSrcLn.get(j));
|
||||
int segNum = reader.parseUnsignedShortVal();
|
||||
segNums.add(segNum);
|
||||
int cPair = reader.parseUnsignedShortVal();
|
||||
List<Long> segOffsets = new ArrayList<>(); // unsigned ints
|
||||
for (int k = 0; k < cPair; k++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
segOffsets.add(reader.parseUnsignedIntVal());
|
||||
}
|
||||
fileSegOffsets.add(segOffsets);
|
||||
List<Integer> segLineNums = new ArrayList<>(); // unsigned shorts
|
||||
for (int k = 0; k < cPair; k++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
segLineNums.add(reader.parseUnsignedShortVal());
|
||||
}
|
||||
fileSegLineNums.add(segLineNums);
|
||||
|
|
|
@ -50,8 +50,8 @@ abstract class C13Section {
|
|||
* @param reader reader to parse from
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation
|
||||
* @return the parsed data
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
static C13Section parse(PdbByteReader reader, TaskMonitor monitor)
|
||||
throws CancelledException, PdbException {
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.io.Writer;
|
|||
import java.util.*;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Debug Data structures for PDB files. There are a number of debug streams that can be processed.
|
||||
|
@ -81,8 +80,8 @@ public class DebugData {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link DebugData}.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link DebugData}
|
||||
*/
|
||||
public DebugData(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
|
@ -91,7 +90,7 @@ public class DebugData {
|
|||
|
||||
/**
|
||||
* Returns the Frame Pointer Omission data
|
||||
* @return the framePointerOmissionData or null if does not exist.
|
||||
* @return the framePointerOmissionData or null if does not exist
|
||||
*/
|
||||
public List<FramePointerOmissionRecord> getFramePointerOmissionData() {
|
||||
return framePointerOmissionData;
|
||||
|
@ -114,8 +113,8 @@ public class DebugData {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link List}<{@link ImageSectionHeader}>.
|
||||
* @return the imageSectionHeaders or null if does not exist.
|
||||
* Returns the {@link List}<{@link ImageSectionHeader}>
|
||||
* @return the imageSectionHeaders or null if does not exist
|
||||
*/
|
||||
public List<ImageSectionHeader> getImageSectionHeaders() {
|
||||
return imageSectionHeaders;
|
||||
|
@ -123,9 +122,9 @@ public class DebugData {
|
|||
|
||||
/**
|
||||
* Returns the {@link List}<{@link ImageSectionHeader}>.
|
||||
* When this return a non-null list the OMAP_FROM_SRC should be
|
||||
* used for remapping global symbols.
|
||||
* @return the imageSectionHeadersOrig or null if does not exist.
|
||||
* When this returns a non-null list the OMAP_FROM_SRC should be
|
||||
* used for remapping global symbols
|
||||
* @return the imageSectionHeadersOrig or null if does not exist
|
||||
*/
|
||||
public List<ImageSectionHeader> getImageSectionHeadersOrig() {
|
||||
return imageSectionHeadersOrig;
|
||||
|
@ -138,17 +137,16 @@ public class DebugData {
|
|||
* 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
|
||||
* {@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.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* {@link #deserialize()} 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
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public void deserializeHeader(PdbByteReader reader, TaskMonitor monitor)
|
||||
public void deserializeHeader(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int debugStreamNumber = reader.parseUnsignedShortVal();
|
||||
debugStreams.add(debugStreamNumber);
|
||||
}
|
||||
|
@ -160,14 +158,13 @@ public class DebugData {
|
|||
|
||||
/**
|
||||
* Deserialize each valid {@link DebugData} stream, based upon valid stream numbers found while
|
||||
* parsing the {@link DebugData} header.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* parsing the {@link DebugData} header
|
||||
* @throws PdbException PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
*/
|
||||
public void deserialize(TaskMonitor monitor)
|
||||
public void deserialize()
|
||||
throws PdbException, CancelledException, IOException {
|
||||
if (debugStreams.isEmpty()) {
|
||||
throw new PdbException(
|
||||
|
@ -180,7 +177,7 @@ public class DebugData {
|
|||
}
|
||||
switch (dbg) {
|
||||
case FRAME_POINTER_OMISSION:
|
||||
deserializeFramePointerOmissionData(streamNum, monitor);
|
||||
deserializeFramePointerOmissionData(streamNum);
|
||||
break;
|
||||
case EXCEPTION:
|
||||
// TODO: implement.
|
||||
|
@ -189,40 +186,40 @@ public class DebugData {
|
|||
// TODO: implement.
|
||||
break;
|
||||
case OMAP_TO_SOURCE:
|
||||
// omapToSource = deserializeOMap(streamNum, monitor);
|
||||
// omapToSource = deserializeOMap(streamNum);
|
||||
break;
|
||||
case OMAP_FROM_SOURCE:
|
||||
omapFromSource = deserializeOMap(streamNum, monitor);
|
||||
omapFromSource = deserializeOMap(streamNum);
|
||||
break;
|
||||
case SECTION_HEADER:
|
||||
imageSectionHeaders = deserializeSectionHeaders(streamNum, monitor);
|
||||
imageSectionHeaders = deserializeSectionHeaders(streamNum);
|
||||
break;
|
||||
case TOKEN_RID_MAP:
|
||||
// TODO: implement.
|
||||
break;
|
||||
case X_DATA:
|
||||
deserializeXData(streamNum, monitor);
|
||||
deserializeXData(streamNum);
|
||||
break;
|
||||
case P_DATA:
|
||||
deserializePData(streamNum, monitor);
|
||||
deserializePData(streamNum);
|
||||
break;
|
||||
case NEW_FRAME_POINTER_OMISSION:
|
||||
// TODO: implement.
|
||||
break;
|
||||
case SECTION_HEADER_ORIG:
|
||||
imageSectionHeadersOrig = deserializeSectionHeaders(streamNum, monitor);
|
||||
imageSectionHeadersOrig = deserializeSectionHeaders(streamNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deserializeFramePointerOmissionData(int streamNum, TaskMonitor monitor)
|
||||
private void deserializeFramePointerOmissionData(int streamNum)
|
||||
throws PdbException, CancelledException, IOException {
|
||||
// TODO: check implementation for completeness.
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
framePointerOmissionData = new ArrayList<>();
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
FramePointerOmissionRecord framePointerOmissionRecord =
|
||||
new FramePointerOmissionRecord();
|
||||
framePointerOmissionRecord.parse(reader);
|
||||
|
@ -230,12 +227,12 @@ public class DebugData {
|
|||
}
|
||||
}
|
||||
|
||||
private SortedMap<Long, Long> deserializeOMap(int streamNum, TaskMonitor monitor)
|
||||
private SortedMap<Long, Long> deserializeOMap(int streamNum)
|
||||
throws PdbException, CancelledException, IOException {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
SortedMap<Long, Long> omap = new TreeMap<>();
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
long v1 = reader.parseUnsignedIntVal();
|
||||
long v2 = reader.parseUnsignedIntVal();
|
||||
omap.put(v1, v2);
|
||||
|
@ -243,12 +240,12 @@ public class DebugData {
|
|||
return omap;
|
||||
}
|
||||
|
||||
private List<ImageSectionHeader> deserializeSectionHeaders(int streamNum, TaskMonitor monitor)
|
||||
private List<ImageSectionHeader> deserializeSectionHeaders(int streamNum)
|
||||
throws PdbException, CancelledException, IOException {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
List<ImageSectionHeader> sectionHeaders = new ArrayList<>();
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
ImageSectionHeader imageSectionHeader = new ImageSectionHeader(pdb);
|
||||
imageSectionHeader.parse(reader);
|
||||
sectionHeaders.add(imageSectionHeader);
|
||||
|
@ -259,11 +256,11 @@ public class DebugData {
|
|||
// TODO: This is incomplete.
|
||||
/**
|
||||
* See the {@link LinkerUnwindInfo} class that was built for and is pertinent to
|
||||
* processing XData.
|
||||
* processing XData
|
||||
*/
|
||||
private void deserializeXData(int streamNum, TaskMonitor monitor)
|
||||
private void deserializeXData(int streamNum)
|
||||
throws PdbException, CancelledException, IOException {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
int streamLength = reader.getLimit();
|
||||
//System.out.println(reader.dump(0x20));
|
||||
RvaVaDebugHeader header = new RvaVaDebugHeader();
|
||||
|
@ -289,9 +286,9 @@ public class DebugData {
|
|||
}
|
||||
|
||||
// TODO: This is incomplete.
|
||||
private void deserializePData(int streamNum, TaskMonitor monitor)
|
||||
private void deserializePData(int streamNum)
|
||||
throws PdbException, CancelledException, IOException {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
pData = new ArrayList<>();
|
||||
int streamLength = reader.getLimit();
|
||||
RvaVaDebugHeader header = new RvaVaDebugHeader();
|
||||
|
@ -310,7 +307,7 @@ public class DebugData {
|
|||
// TODO: current partial implementation does not work (throws exception)
|
||||
// for ucrtbase.dll arm64. Need to look at this closer.
|
||||
// while (reader.hasMore()) {
|
||||
// monitor.checkCanceled();
|
||||
// pdb.checkCanceled();
|
||||
// ImageFunctionEntry entry = new ImageFunctionEntry();
|
||||
// entry.deserialize(reader);
|
||||
// pData.add(entry);
|
||||
|
@ -340,17 +337,19 @@ public class DebugData {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps the {@link DebugData}. This package-protected method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the {@link DebugData}. This package-protected method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void dump(Writer writer) throws IOException {
|
||||
void dump(Writer writer) throws IOException, CancelledException {
|
||||
writer.write("DebugData---------------------------------------------------\n");
|
||||
dumpDebugStreamList(writer);
|
||||
|
||||
writer.write("FramePointerOmissionData------------------------------------\n");
|
||||
if (framePointerOmissionData != null) {
|
||||
for (FramePointerOmissionRecord framePointerOmissionRecord : framePointerOmissionData) {
|
||||
pdb.checkCanceled();
|
||||
framePointerOmissionRecord.dump(writer);
|
||||
}
|
||||
}
|
||||
|
@ -360,16 +359,18 @@ public class DebugData {
|
|||
// if (omapToSource != null) {
|
||||
// int num = 0;
|
||||
// for (Map.Entry<Long, Long> entry : omapToSource.entrySet()) {
|
||||
// pdb.checkCanceled();
|
||||
// writer.write(String.format("0X%08X: 0X%012X, 0X%012X\n", num++, entry.getKey(),
|
||||
// entry.getValue()));
|
||||
// }
|
||||
// }
|
||||
// writer.write("End OmapToSource--------------------------------------------\n");
|
||||
|
||||
//
|
||||
writer.write("OmapFromSource----------------------------------------------\n");
|
||||
if (omapFromSource != null) {
|
||||
int num = 0;
|
||||
for (Map.Entry<Long, Long> entry : omapFromSource.entrySet()) {
|
||||
pdb.checkCanceled();
|
||||
writer.write(String.format("0X%08X: 0X%012X, 0X%012X\n", num++, entry.getKey(),
|
||||
entry.getValue()));
|
||||
}
|
||||
|
@ -380,6 +381,7 @@ public class DebugData {
|
|||
if (imageSectionHeaders != null) {
|
||||
int sectionNum = 0;
|
||||
for (ImageSectionHeader imageSectionHeader : imageSectionHeaders) {
|
||||
pdb.checkCanceled();
|
||||
imageSectionHeader.dump(writer, sectionNum++);
|
||||
}
|
||||
}
|
||||
|
@ -389,6 +391,7 @@ public class DebugData {
|
|||
if (imageSectionHeadersOrig != null) {
|
||||
int sectionNum = 0;
|
||||
for (ImageSectionHeader imageSectionHeader : imageSectionHeadersOrig) {
|
||||
pdb.checkCanceled();
|
||||
imageSectionHeader.dump(writer, sectionNum++);
|
||||
}
|
||||
}
|
||||
|
@ -397,6 +400,7 @@ public class DebugData {
|
|||
writer.write("PData-------------------------------------------------------\n");
|
||||
if (pData != null) {
|
||||
for (ImageFunctionEntry entry : pData) {
|
||||
pdb.checkCanceled();
|
||||
// TODO: need to output more if/when more PData is available (e.g., interpretation
|
||||
// of XData.
|
||||
writer.append(entry.toString());
|
||||
|
@ -408,14 +412,16 @@ public class DebugData {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps the DebugStreamList. This package-protected method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the DebugStreamList. This package-protected method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void dumpDebugStreamList(Writer writer) throws IOException {
|
||||
private void dumpDebugStreamList(Writer writer) throws IOException, CancelledException {
|
||||
writer.write("StreamList--------------------------------------------------\n");
|
||||
int i = 0;
|
||||
for (int strmNumber : debugStreams) {
|
||||
pdb.checkCanceled();
|
||||
writer.write(String.format("StrmNumber[%02d]: %04x\n", i++, strmNumber));
|
||||
}
|
||||
writer.write("End StreamList----------------------------------------------\n");
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
public class EmptyTPI extends AbstractTypeProgramInterface {
|
||||
public class EmptyTPI extends TypeProgramInterface {
|
||||
|
||||
EmptyTPI(AbstractPdb pdb) {
|
||||
super(pdb, RecordCategory.TYPE, -1);
|
||||
|
|
|
@ -22,7 +22,6 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.msf.MsfStream;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Iterator for Global Reference Offsets section of module stream. This iterator returns
|
||||
|
@ -34,25 +33,21 @@ class GlobalReferenceIterator implements ParsingIterator<MsSymbolIterator> {
|
|||
private AbstractPdb pdb;
|
||||
private int symbolsStreamNumber;
|
||||
|
||||
private TaskMonitor monitor;
|
||||
|
||||
private GlobalReferenceOffsetIterator offsetIterator = null;
|
||||
|
||||
private MsSymbolIterator currentGlobalSymbolIterator = null;
|
||||
|
||||
/**
|
||||
* An Iterator of Global Reference Symbol Iterators (iterator of iterators).
|
||||
* An Iterator of Global Reference Symbol Iterators (iterator of iterators)
|
||||
* @param pdb {@link AbstractPdb} that owns the Symbols to be parsed
|
||||
* @param reader PdbByteReader containing only Global Reference Offsets information and in
|
||||
* newly constructed state
|
||||
* @param monitor {@link TaskMonitor} used for checking user cancellation
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public GlobalReferenceIterator(AbstractPdb pdb, PdbByteReader reader, TaskMonitor monitor)
|
||||
public GlobalReferenceIterator(AbstractPdb pdb, PdbByteReader reader)
|
||||
throws CancelledException, PdbException {
|
||||
this.pdb = pdb;
|
||||
this.monitor = monitor;
|
||||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||
if (debugInfo == null) {
|
||||
throw new PdbException(
|
||||
|
@ -102,7 +97,7 @@ class GlobalReferenceIterator implements ParsingIterator<MsSymbolIterator> {
|
|||
Long offset = offsetIterator.next();
|
||||
PdbByteReader reader =
|
||||
pdb.getReaderForStreamNumber(symbolsStreamNumber, offset.intValue(),
|
||||
MsfStream.MAX_STREAM_LENGTH, monitor);
|
||||
MsfStream.MAX_STREAM_LENGTH);
|
||||
currentGlobalSymbolIterator = new MsSymbolIterator(pdb, reader);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
|
|
@ -34,7 +34,7 @@ class GlobalReferenceOffsetIterator implements ParsingIterator<Long> {
|
|||
* @param reader PdbByteReader containing only Global Reference Offsets information and in
|
||||
* newly constructed state
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public GlobalReferenceOffsetIterator(PdbByteReader reader)
|
||||
throws CancelledException, PdbException {
|
||||
|
@ -80,7 +80,7 @@ class GlobalReferenceOffsetIterator implements ParsingIterator<Long> {
|
|||
|
||||
/**
|
||||
* Reads and validates size field; leaves reader pointing at first record.
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
private void processHeader() throws PdbException {
|
||||
int sizeField = reader.parseInt();
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents Global Symbol Information component of a PDB file. This class is only
|
||||
|
@ -41,32 +40,32 @@ public class GlobalSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserialize the {@link GlobalSymbolInformation} from the appropriate stream in the Pdb.
|
||||
* @param streamNumber the stream number containing the information to deserialize.
|
||||
* @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.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserialize the {@link GlobalSymbolInformation} from the appropriate stream in the Pdb
|
||||
* @param streamNumber the stream number containing the information to deserialize
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@Override
|
||||
void deserialize(int streamNumber, TaskMonitor monitor)
|
||||
void deserialize(int streamNumber)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
super.deserialize(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
deserializeHashTable(reader, monitor);
|
||||
super.deserialize(streamNumber);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
deserializeHashTable(reader);
|
||||
|
||||
// Organize the information
|
||||
generateSymbolsList(monitor);
|
||||
generateSymbolsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping information from this {@link GlobalSymbolInformation}.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* Debug method for dumping information from this {@link GlobalSymbolInformation}
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@Override
|
||||
void dump(Writer writer) throws IOException {
|
||||
void dump(Writer writer) throws IOException, CancelledException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("GlobalSymbolInformation-------------------------------------\n");
|
||||
dumpHashHeader(builder);
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
|
||||
/**
|
||||
* Parser, extending {@link TypeProgramInterfaceParser}, for detecting and returning the
|
||||
* appropriate {@link AbstractTypeProgramInterface} format to be used as the Item Program
|
||||
* appropriate {@link TypeProgramInterface} format to be used as the Item Program
|
||||
* Interface for the filename given.
|
||||
*/
|
||||
public class ItemProgramInterfaceParser extends TypeProgramInterfaceParser {
|
||||
|
@ -27,8 +27,8 @@ public class ItemProgramInterfaceParser extends TypeProgramInterfaceParser {
|
|||
private static final int ITEM_PROGRAM_INTERFACE_STREAM_NUMBER = 4;
|
||||
|
||||
/**
|
||||
* Returns the standard stream number that contains the serialized Item Program Interface.
|
||||
* @return The standard stream number that contains the Item Program Interface.
|
||||
* Returns the standard stream number that contains the serialized Item Program Interface
|
||||
* @return the standard stream number that contains the Item Program Interface
|
||||
*/
|
||||
@Override
|
||||
protected int getStreamNumber() {
|
||||
|
@ -38,8 +38,8 @@ public class ItemProgramInterfaceParser extends TypeProgramInterfaceParser {
|
|||
|
||||
/**
|
||||
* Returns the appropriate {@link RecordCategory} needed while processing
|
||||
* the Type Program Interface} (vs. Item Program Interface).
|
||||
* @return {@link RecordCategory#ITEM}.
|
||||
* the Type Program Interface} (vs. Item Program Interface)
|
||||
* @return {@link RecordCategory#ITEM}
|
||||
*/
|
||||
@Override
|
||||
protected RecordCategory getCategory() {
|
||||
|
@ -48,10 +48,10 @@ public class ItemProgramInterfaceParser extends TypeProgramInterfaceParser {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is not a name in the name table assigned to the stream number for
|
||||
* the IPI.
|
||||
* @param nameTable the nametable that contains the stream/name map
|
||||
* @return {@code true} if no name associated with the IPI stream number.
|
||||
* Returns {@code true} if there is not a name in the name table assigned to the stream number
|
||||
* for the IPI
|
||||
* @param nameTable the name table that contains the stream/name map
|
||||
* @return {@code true} if no name associated with the IPI stream number
|
||||
*/
|
||||
public static boolean hackCheckNoNameForStream(NameTable nameTable) {
|
||||
String name = nameTable.getNameFromStreamNumber(ITEM_PROGRAM_INTERFACE_STREAM_NUMBER);
|
||||
|
|
|
@ -22,16 +22,15 @@ import java.util.*;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.MsfStream;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* <B> Note that this class is new, in-progress creation, being designed as a better interface for
|
||||
* getting information for any particular module (stream) in a more random-access manner.</B>
|
||||
* <P>
|
||||
* This class represents Module Stream data of a PDB file. This is different from the
|
||||
* {@link AbstractModuleInformation} and children classes that are parsed from the DBI stream,
|
||||
* {@link ModuleInformation} and children classes that are parsed from the DBI stream,
|
||||
* which describes (or is control information for) what is the stream from which this
|
||||
* {@link Module} is parsed. Note that we use the {@link AbstractModuleInformation} as one of
|
||||
* {@link Module} is parsed. Note that we use the {@link ModuleInformation} as one of
|
||||
* the construction parameter to this class.
|
||||
* <P>
|
||||
* This class is only suitable for reading; not for writing or modifying a PDB.
|
||||
|
@ -42,8 +41,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
public class Module {
|
||||
|
||||
private AbstractPdb pdb;
|
||||
private AbstractModuleInformation moduleInformation;
|
||||
private TaskMonitor monitor;
|
||||
private ModuleInformation moduleInformation;
|
||||
|
||||
private int streamNumber;
|
||||
private MsfStream stream = null;
|
||||
|
@ -61,17 +59,15 @@ public class Module {
|
|||
private boolean doDumpGlobalRefererenceInfo = false;
|
||||
|
||||
//==============================================================================================
|
||||
public Module(AbstractPdb pdb, AbstractModuleInformation moduleInformation,
|
||||
TaskMonitor monitor) {
|
||||
public Module(AbstractPdb pdb, ModuleInformation moduleInformation) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
Objects.requireNonNull(moduleInformation, "moduleInformation cannot be null");
|
||||
this.pdb = pdb;
|
||||
this.moduleInformation = moduleInformation;
|
||||
this.monitor = monitor;
|
||||
precalculateStreamLocations();
|
||||
}
|
||||
|
||||
public AbstractModuleInformation getModuleInformation() {
|
||||
public ModuleInformation getModuleInformation() {
|
||||
return moduleInformation;
|
||||
}
|
||||
|
||||
|
@ -115,10 +111,9 @@ public class Module {
|
|||
}
|
||||
try {
|
||||
PdbByteReader reader =
|
||||
pdb.getReaderForStreamNumber(streamNumber, offsetLines, sizeLines,
|
||||
monitor);
|
||||
pdb.getReaderForStreamNumber(streamNumber, offsetLines, sizeLines);
|
||||
// This parser has not been tested with real data
|
||||
C11Lines c11Lines = C11Lines.parse(pdb, reader, monitor);
|
||||
C11Lines c11Lines = C11Lines.parse(pdb, reader);
|
||||
return c11Lines;
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
@ -193,7 +188,7 @@ public class Module {
|
|||
* Returns a C13SectionIterator that iterators over all C13Sections of this module
|
||||
* @return the iterator
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public C13SectionIterator<C13Section> getC13SectionIterator()
|
||||
throws CancelledException, PdbException {
|
||||
|
@ -206,13 +201,13 @@ public class Module {
|
|||
* @param clazz The class of the filter type
|
||||
* @return the iterator
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public <T extends C13Section> C13SectionIterator<T> getC13SectionFilteredIterator(
|
||||
Class<T> clazz) throws CancelledException, PdbException {
|
||||
PdbByteReader c13SectionReader = getC13LinesReader();
|
||||
C13SectionIterator<T> iterator =
|
||||
new C13SectionIterator<>(c13SectionReader, clazz, true, monitor);
|
||||
new C13SectionIterator<>(c13SectionReader, clazz, true, pdb.getMonitor());
|
||||
return iterator;
|
||||
}
|
||||
|
||||
|
@ -225,7 +220,7 @@ public class Module {
|
|||
* nested blocks until the closing END is found for the GPROC32
|
||||
* @return the iterator
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public GlobalReferenceOffsetIterator getGlobalReferenceOffsetIterator()
|
||||
throws CancelledException, PdbException {
|
||||
|
@ -245,13 +240,13 @@ public class Module {
|
|||
* nested blocks until the closing END is found for the GPROC32
|
||||
* @return the iterator
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
public GlobalReferenceIterator getGlobalReferenceIterator()
|
||||
throws CancelledException, PdbException {
|
||||
PdbByteReader globalRefsReader = getGlobalRefsReader();
|
||||
GlobalReferenceIterator iterator =
|
||||
new GlobalReferenceIterator(pdb, globalRefsReader, monitor);
|
||||
new GlobalReferenceIterator(pdb, globalRefsReader);
|
||||
return iterator;
|
||||
}
|
||||
|
||||
|
@ -282,7 +277,7 @@ public class Module {
|
|||
}
|
||||
|
||||
try {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
reader.skip(offset);
|
||||
try {
|
||||
if (size == -1) {
|
||||
|
@ -312,11 +307,11 @@ public class Module {
|
|||
// is loaded into the class (note that as of this writing, the PdbByteReader still contains
|
||||
// full byte array of data, consuming memory at the time of use).
|
||||
/**
|
||||
* Dumps this class to a Writer.
|
||||
* Dumps this class to a Writer
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
*/
|
||||
void dump(Writer writer)
|
||||
throws CancelledException, PdbException, IOException {
|
||||
|
@ -341,6 +336,7 @@ public class Module {
|
|||
writer.write("Symbols-----------------------------------------------------\n");
|
||||
MsSymbolIterator symbolIterator = getSymbolIterator();
|
||||
while (symbolIterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
AbstractMsSymbol symbol = symbolIterator.next();
|
||||
writer.append(symbol.toString());
|
||||
}
|
||||
|
@ -365,6 +361,7 @@ public class Module {
|
|||
C13SectionIterator<C13Section> c13Iterator =
|
||||
getC13SectionFilteredIterator(C13Section.class);
|
||||
while (c13Iterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
C13Section c13Section = c13Iterator.next();
|
||||
c13Section.dump(writer);
|
||||
}
|
||||
|
@ -375,6 +372,7 @@ public class Module {
|
|||
// C13SectionIterator<DummyC13Symbols> c13SymbolsIterator =
|
||||
// getC13SectionFilteredIterator(DummyC13Symbols.class);
|
||||
// while (c13SymbolsIterator.hasNext()) {
|
||||
// pdb.checkCanceled();
|
||||
// DummyC13Symbols dummyC13Symbols = c13SymbolsIterator.next();
|
||||
// dummyC13Symbols.dump(writer);
|
||||
// }
|
||||
|
@ -382,6 +380,7 @@ public class Module {
|
|||
// C13SectionIterator<C13Lines> c13LinesIterator =
|
||||
// getC13SectionFilteredIterator(C13Lines.class);
|
||||
// while (c13LinesIterator.hasNext()) {
|
||||
// pdb.checkCanceled();
|
||||
// C13Lines myC13Lines = c13LinesIterator.next();
|
||||
// myC13Lines.dump(writer);
|
||||
// }
|
||||
|
@ -395,6 +394,7 @@ public class Module {
|
|||
GlobalReferenceOffsetIterator globalRefsOffsetIterator =
|
||||
getGlobalReferenceOffsetIterator();
|
||||
while (globalRefsOffsetIterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
Long val = globalRefsOffsetIterator.next();
|
||||
writer.append(String.format("0x%08x\n", val));
|
||||
tmp.add(val);
|
||||
|
@ -420,6 +420,7 @@ public class Module {
|
|||
GlobalReferenceIterator globalReferenceIterator =
|
||||
getGlobalReferenceIterator();
|
||||
while (globalReferenceIterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
MsSymbolIterator symIter = globalReferenceIterator.next();
|
||||
if (symIter.hasNext()) {
|
||||
AbstractMsSymbol sym = symIter.next();
|
||||
|
|
|
@ -24,13 +24,13 @@ import java.util.*;
|
|||
* We have intended to implement according to the Microsoft PDB API (source); see the API for
|
||||
* truth.
|
||||
*/
|
||||
public abstract class AbstractModuleInformation {
|
||||
public abstract class ModuleInformation {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
//==============================================================================================
|
||||
protected long modulePointer;
|
||||
protected AbstractSectionContribution sectionContribution;
|
||||
protected SectionContribution sectionContribution;
|
||||
protected boolean writtenSinceOpen;
|
||||
// TODO: consider what to do (gets parsed for 600 between 500 items. Want only in 600,
|
||||
// but would have to break up the deserialize and dumpInternal methods. Issue might be,
|
||||
|
@ -61,46 +61,46 @@ public abstract class AbstractModuleInformation {
|
|||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
public AbstractModuleInformation(AbstractPdb pdb) {
|
||||
public ModuleInformation(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
this.pdb = pdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of files contributing to the module.
|
||||
* @return Number of files.
|
||||
* Returns the number of files contributing to the module
|
||||
* @return number of files
|
||||
*/
|
||||
public int getNumFilesContributing() {
|
||||
return numFilesContributing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of offsets for the module.
|
||||
* @return Offsets.
|
||||
* Returns list of offsets for the module
|
||||
* @return offsets
|
||||
*/
|
||||
public List<Integer> getOffsetsArray() {
|
||||
return offsetsArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of file names for the module.
|
||||
* @return File names.
|
||||
* Returns list of file names for the module
|
||||
* @return file names
|
||||
*/
|
||||
public List<String> getFilenamesArray() {
|
||||
return filenamesArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream number containing debug information.
|
||||
* @return Stream number.
|
||||
* Returns the stream number containing debug information
|
||||
* @return stream number
|
||||
*/
|
||||
public int getStreamNumberDebugInformation() {
|
||||
return streamNumberDebugInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the local symbols debug information.
|
||||
* @return Size of the local symbols debug information.
|
||||
* Returns the size of the local symbols debug information
|
||||
* @return size of the local symbols debug information
|
||||
*/
|
||||
public int getSizeLocalSymbolsDebugInformation() {
|
||||
return sizeLocalSymbolsDebugInformation;
|
||||
|
@ -108,7 +108,7 @@ public abstract class AbstractModuleInformation {
|
|||
|
||||
/**
|
||||
* Returns the size of the older-style line number information
|
||||
* @return Size of the older-style line number information
|
||||
* @return size of the older-style line number information
|
||||
*/
|
||||
public int getSizeLineNumberDebugInformation() {
|
||||
return sizeLineNumberDebugInformation;
|
||||
|
@ -116,25 +116,25 @@ public abstract class AbstractModuleInformation {
|
|||
|
||||
/**
|
||||
* Returns the size of the C13-style line number information
|
||||
* @return Size of the C13-style line number information
|
||||
* @return size of the C13-style line number information
|
||||
*/
|
||||
public int getSizeC13StyleLineNumberInformation() {
|
||||
return sizeC13StyleLineNumberInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the module.
|
||||
* @return Name of the module.
|
||||
* Returns the name of the module
|
||||
* @return name of the module
|
||||
*/
|
||||
public String getModuleName() {
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link AbstractSectionContribution} of the module.
|
||||
* @return {@link AbstractSectionContribution} of the module.
|
||||
* Returns {@link SectionContribution} of the module
|
||||
* @return {@link SectionContribution} of the module
|
||||
*/
|
||||
public AbstractSectionContribution getSectionContribution() {
|
||||
public SectionContribution getSectionContribution() {
|
||||
return sectionContribution;
|
||||
}
|
||||
|
||||
|
@ -151,9 +151,9 @@ public abstract class AbstractModuleInformation {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the module.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException upon error parsing a string name.
|
||||
* Deserializes the module
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon error parsing a string name
|
||||
*/
|
||||
protected void deserialize(PdbByteReader reader) throws PdbException {
|
||||
modulePointer = reader.parseUnsignedIntVal();
|
||||
|
@ -186,15 +186,15 @@ public abstract class AbstractModuleInformation {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Additionals. Abstract method filled in by instances to parse additional
|
||||
* data pertinent to themselves.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException upon error parsing a string name.
|
||||
* data pertinent to themselves
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon error parsing a string name
|
||||
*/
|
||||
protected abstract void parseAdditionals(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Dumps the Additionals. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the Additionals. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
protected abstract String dumpAdditionals();
|
||||
|
||||
|
@ -211,8 +211,8 @@ public abstract class AbstractModuleInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps this module. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps this module. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
String dump() {
|
||||
StringBuilder builder = new StringBuilder();
|
|
@ -16,9 +16,9 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractModuleInformation} for Microsoft v5.00 PDB.
|
||||
* This class is the version of {@link ModuleInformation} for Microsoft v5.00 PDB.
|
||||
*/
|
||||
public class ModuleInformation500 extends AbstractModuleInformation {
|
||||
public class ModuleInformation500 extends ModuleInformation {
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractModuleInformation} for Microsoft v6.00 PDB.
|
||||
* This class is the version of {@link ModuleInformation} for Microsoft v6.00 PDB.
|
||||
*/
|
||||
public class ModuleInformation600 extends AbstractModuleInformation {
|
||||
public class ModuleInformation600 extends ModuleInformation {
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.util.*;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents Name Table component of a PDB file. This class is only
|
||||
|
@ -54,8 +53,8 @@ public class NameTable {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this Name Table.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this Name Table
|
||||
*/
|
||||
public NameTable(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
|
@ -63,18 +62,18 @@ public class NameTable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a name from the Name Table pertaining to the index argument.
|
||||
* @param index Index of the name to retrieve.
|
||||
* @return Name retrieved for the index.
|
||||
* Returns a name from the Name Table pertaining to the index argument
|
||||
* @param index index of the name to retrieve
|
||||
* @return name retrieved for the index
|
||||
*/
|
||||
public String getNameFromStreamNumber(int index) {
|
||||
return namesByStreamNumber.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index of the name argument in the {@link NameTable}.
|
||||
* @param name Name to look up.
|
||||
* @return Index of the name.
|
||||
* Returns an index of the name argument in the {@link NameTable}
|
||||
* @param name name to look up
|
||||
* @return index of the name
|
||||
*/
|
||||
public int getStreamNumberFromName(String name) {
|
||||
Integer x = streamNumbersByName.getOrDefault(name, -1);
|
||||
|
@ -83,9 +82,9 @@ public class NameTable {
|
|||
|
||||
/**
|
||||
* Returns a name from the Name Table pertaining to the byte-offset in the block of names for
|
||||
* the table.
|
||||
* @param offset Byte-offset of the name in the {@link NameTable} block.
|
||||
* @return Name found at offset.
|
||||
* the table
|
||||
* @param offset byte-offset of the name in the {@link NameTable} block
|
||||
* @return name found at offset
|
||||
*/
|
||||
public String getNameStringFromOffset(int offset) {
|
||||
if (namesByOffset == null) {
|
||||
|
@ -96,9 +95,9 @@ public class NameTable {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a basic object.
|
||||
* Note: not all values are initialized. Add a paired offset and {@link String} name.
|
||||
* @param offset Offset part of pair.
|
||||
* @param name Name part of pair.
|
||||
* Note: not all values are initialized. Add a paired offset and {@link String} name
|
||||
* @param offset offset part of pair
|
||||
* @param name name part of pair
|
||||
*/
|
||||
public void forTestingOnlyAddOffsetNamePair(int offset, String name) {
|
||||
if (namesByOffset == null) {
|
||||
|
@ -119,15 +118,14 @@ public class NameTable {
|
|||
// Ghidra user can ad-hoc apply interpretations to those fields? Needs investigation, but
|
||||
// not critical at this time.
|
||||
/**
|
||||
* Deserializes the Directory.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @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.
|
||||
* @throws PdbException upon error parsing a string.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Directory
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a string
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializeDirectory(PdbByteReader reader, TaskMonitor monitor)
|
||||
void deserializeDirectory(PdbByteReader reader)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
|
||||
// Get the buffer of strings
|
||||
|
@ -152,10 +150,10 @@ public class NameTable {
|
|||
streamNumbers = new int[numPairs];
|
||||
|
||||
// Read Present Set. Not really needed by us, as we use the java HashMap.
|
||||
presentList.parse(reader, monitor);
|
||||
presentList.parse(reader, pdb.getMonitor());
|
||||
|
||||
// Read Deleted Set. Not really needed by us, as we use the java HashMap.
|
||||
deletedList.parse(reader, monitor);
|
||||
deletedList.parse(reader, pdb.getMonitor());
|
||||
|
||||
// Read values of index into buffer and name index. Load the HashMaps.
|
||||
// Since we are using the java HashMap, we do not need to mimic the
|
||||
|
@ -163,7 +161,7 @@ public class NameTable {
|
|||
// of domainSize) and do not need to store the domain and range items
|
||||
// in a list indexed by i.
|
||||
for (int i = 0; i < numPairs; i++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int bufOffset = reader.parseInt();
|
||||
int streamNumber = reader.parseInt();
|
||||
nameBufferReader.setIndex(bufOffset);
|
||||
|
@ -174,7 +172,7 @@ public class NameTable {
|
|||
namesByStreamNumber.put(streamNumber, name);
|
||||
streamNumbersByName.put(name, streamNumber);
|
||||
}
|
||||
deserializeNameTableStreams(monitor);
|
||||
deserializeNameTableStreams();
|
||||
}
|
||||
|
||||
// TODO: Reduce code complexity once we know the details for the various cases. Probably
|
||||
|
@ -182,19 +180,18 @@ public class NameTable {
|
|||
// find here.
|
||||
/**
|
||||
* Deserializes Name Table Streams. An offset-to-string map is created for each stream; each
|
||||
* map is placed into a stream-number-to-map map.
|
||||
* @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.
|
||||
* @throws PdbException upon error parsing a string.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* map is placed into a stream-number-to-map map
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a string
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializeNameTableStreams(TaskMonitor monitor)
|
||||
void deserializeNameTableStreams()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
for (int streamNumber : streamNumbers) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
Map<Integer, String> stringsByOffset = new HashMap<>();
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
if (reader.getLimit() >= 12) {
|
||||
long hdrMagic = reader.parseUnsignedIntVal();
|
||||
int hdrVer = reader.parseInt();
|
||||
|
@ -205,7 +202,7 @@ public class NameTable {
|
|||
int length = reader.parseInt();
|
||||
PdbByteReader stringReader = reader.getSubPdbByteReader(length);
|
||||
while (stringReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int offset = stringReader.getIndex();
|
||||
String string = stringReader.parseNullTerminatedUtf8String();
|
||||
stringsByOffset.put(offset, string);
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.AbstractMsf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -31,20 +31,20 @@ public class Pdb200 extends AbstractPdb {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf {@link AbstractMsf} foundation for the PDB.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration or error in processing components.
|
||||
* Constructor
|
||||
* @param msf {@link Msf} foundation for the PDB
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration or error in processing components
|
||||
*/
|
||||
Pdb200(AbstractMsf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
Pdb200(Msf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
super(msf, pdbOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
void deserializeIdentifiersOnly(TaskMonitor monitor)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,9 @@ public class Pdb200 extends AbstractPdb {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserializeDirectory(TaskMonitor monitor)
|
||||
void deserializeDirectory()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.AbstractMsf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -31,20 +31,20 @@ public class Pdb400 extends AbstractPdb {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf {@link AbstractMsf} foundation for the PDB.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration or error in processing components.
|
||||
* Constructor
|
||||
* @param msf {@link Msf} foundation for the PDB
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration or error in processing components
|
||||
*/
|
||||
Pdb400(AbstractMsf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
Pdb400(Msf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
super(msf, pdbOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
void deserializeIdentifiersOnly(TaskMonitor monitor)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,11 @@ public class Pdb400 extends AbstractPdb {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserializeDirectory(TaskMonitor monitor)
|
||||
void deserializeDirectory()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
deserializeParameters(reader, monitor);
|
||||
deserializeParameters(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.AbstractMsf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -31,20 +31,20 @@ public class Pdb700 extends AbstractPdb {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf {@link AbstractMsf} foundation for the PDB.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration or error in processing components.
|
||||
* Constructor
|
||||
* @param msf {@link Msf} foundation for the PDB
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration or error in processing components
|
||||
*/
|
||||
Pdb700(AbstractMsf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
Pdb700(Msf msf, PdbReaderOptions pdbOptions) throws IOException, PdbException {
|
||||
super(msf, pdbOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
void deserializeIdentifiersOnly(TaskMonitor monitor)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
guid = reader.parseGUID();
|
||||
}
|
||||
|
@ -53,12 +53,12 @@ public class Pdb700 extends AbstractPdb {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserializeDirectory(TaskMonitor monitor)
|
||||
void deserializeDirectory()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbByteReader reader = getDirectoryReader(monitor);
|
||||
PdbByteReader reader = getDirectoryReader();
|
||||
deserializeVersionSignatureAge(reader);
|
||||
guid = reader.parseGUID();
|
||||
deserializeParameters(reader, monitor);
|
||||
deserializeParameters(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,8 +76,8 @@ public class Pdb700 extends AbstractPdb {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Dumps the GUID. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the GUID. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
protected String dumpGUID() {
|
||||
if (guid == null) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.*;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents DebugInfo (DBI) component of a PDB file.
|
||||
|
@ -65,8 +64,8 @@ public abstract class PdbDebugInfo {
|
|||
protected int lengthSectionMap = 0; // signed 32-bit
|
||||
protected int lengthFileInformation = 0; // signed 32-bit
|
||||
|
||||
protected List<AbstractModuleInformation> moduleInformationList = new ArrayList<>();
|
||||
protected List<AbstractSectionContribution> sectionContributionList = new ArrayList<>();
|
||||
protected List<ModuleInformation> moduleInformationList = new ArrayList<>();
|
||||
protected List<SectionContribution> sectionContributionList = new ArrayList<>();
|
||||
protected List<SegmentMapDescription> segmentMapList = new ArrayList<>();
|
||||
|
||||
protected SymbolRecords symbolRecords;
|
||||
|
@ -83,9 +82,9 @@ public abstract class PdbDebugInfo {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this Database Interface.
|
||||
* @param streamNumber The stream number of the stream containing the Database Interface.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this debug info
|
||||
* @param streamNumber the stream number of the stream containing the debug info
|
||||
*/
|
||||
public PdbDebugInfo(AbstractPdb pdb, int streamNumber) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
|
@ -97,8 +96,8 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes needed to store the version number.
|
||||
* @return The number of bytes needed to store the version number.
|
||||
* Returns the number of bytes needed to store the version number
|
||||
* @return the number of bytes needed to store the version number
|
||||
*/
|
||||
public static int getVersionNumberSize() {
|
||||
return VERSION_NUMBER_SIZE;
|
||||
|
@ -109,29 +108,28 @@ public abstract class PdbDebugInfo {
|
|||
* The PDB is updated with dbiAge and targetProcessor during deserialization
|
||||
* of new DBI header.
|
||||
* @param headerOnly if true only the DBI header fields will be parsed
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return The version number of the Database Interface.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* @return the version number of the debug info
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public long deserialize(boolean headerOnly, TaskMonitor monitor)
|
||||
public long deserialize(boolean headerOnly)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
if (headerOnly) {
|
||||
PdbByteReader reader =
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, getHeaderLength(), monitor);
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, getHeaderLength());
|
||||
deserializeHeader(reader);
|
||||
}
|
||||
else {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
deserializeHeader(reader);
|
||||
deserializeInternalSubstreams(reader, monitor);
|
||||
deserializeAdditionalSubstreams(monitor);
|
||||
deserializeInternalSubstreams(reader);
|
||||
deserializeAdditionalSubstreams();
|
||||
// BELOW: NEW STUFF FROM REFACTOR/REWORK (can be duplicative with other stuff)
|
||||
if (doNewStuff) {
|
||||
parseModules(monitor);
|
||||
compareSymbols(monitor); //temporary to ensure same results with previous work.
|
||||
parseModules();
|
||||
compareSymbols(); //temporary to ensure same results with previous work.
|
||||
}
|
||||
// ABOVE: NEW STUFF FROM REFACTOR/REWORK (can be duplicative with other stuff)
|
||||
}
|
||||
|
@ -139,7 +137,7 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of modules.
|
||||
* Returns the number of modules
|
||||
* @return the number of modules
|
||||
*/
|
||||
public int getNumModules() {
|
||||
|
@ -147,24 +145,24 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of {@link AbstractModuleInformation}, indexed by the module number.
|
||||
* @return List of {@link AbstractModuleInformation}.
|
||||
* Returns the list of {@link ModuleInformation}, indexed by the module number
|
||||
* @return list of {@link ModuleInformation}
|
||||
*/
|
||||
public List<AbstractModuleInformation> getModuleInformationList() {
|
||||
public List<ModuleInformation> getModuleInformationList() {
|
||||
return moduleInformationList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractModuleInformation}, based on the moduleNumber.
|
||||
* @param moduleNumber The module number being requested (1 to {@link #getNumModules()}).
|
||||
* @return {@link AbstractModuleInformation} for the moduleNumber provided.
|
||||
* @throws PdbException Upon moduleNumber out of range or no module information.
|
||||
* Returns the {@link ModuleInformation}, based on the moduleNumber
|
||||
* @param moduleNumber the module number being requested (1 to {@link #getNumModules()})
|
||||
* @return {@link ModuleInformation} for the moduleNumber provided
|
||||
* @throws PdbException upon moduleNumber out of range or no module information
|
||||
*/
|
||||
public AbstractModuleInformation getModuleInformation(int moduleNumber) throws PdbException {
|
||||
public ModuleInformation getModuleInformation(int moduleNumber) throws PdbException {
|
||||
if (moduleNumber < 1 || moduleNumber > moduleInformationList.size()) {
|
||||
throw new PdbException("ModuleNumber out of range: " + moduleNumber);
|
||||
}
|
||||
AbstractModuleInformation moduleInfo = moduleInformationList.get(moduleNumber - 1);
|
||||
ModuleInformation moduleInfo = moduleInformationList.get(moduleNumber - 1);
|
||||
if (moduleInfo == null) {
|
||||
throw new PdbException("Null AbstractModuleInformation");
|
||||
}
|
||||
|
@ -172,20 +170,20 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of combined global/public symbols.
|
||||
* Returns the list of combined global/public symbols
|
||||
* @return {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
||||
* symbols.
|
||||
* symbols
|
||||
*/
|
||||
public Map<Long, AbstractMsSymbol> getSymbolsByOffset() {
|
||||
return symbolRecords.getSymbolsByOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer-offset-to-symbol map for the module as specified by moduleNumber.
|
||||
* @param moduleNumber The number ID of the module for which to return the list.
|
||||
* Returns the buffer-offset-to-symbol map for the module as specified by moduleNumber
|
||||
* @param moduleNumber the number ID of the module for which to return the list
|
||||
* @return {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
||||
* symbols for the specified module.
|
||||
* @throws PdbException Upon moduleNumber out of range or no module information.
|
||||
* symbols for the specified module
|
||||
* @throws PdbException upon moduleNumber out of range or no module information
|
||||
*/
|
||||
public Map<Long, AbstractMsSymbol> getModuleSymbolsByOffset(int moduleNumber)
|
||||
throws PdbException {
|
||||
|
@ -200,10 +198,10 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Returns the {@link AbstractMsSymbol} from the main symbols for the
|
||||
* actual symbol record offset (which is past the length and symbol type fields).
|
||||
* actual symbol record offset (which is past the length and symbol type fields)
|
||||
* @param offset the offset of the symbol (beyond length and symbol type fields); this is the
|
||||
* offset value specified by many symbol type records.
|
||||
* @return the symbol group for the module or null if not found.
|
||||
* offset value specified by many symbol type records
|
||||
* @return the symbol group for the module or null if not found
|
||||
*/
|
||||
public AbstractMsSymbol getSymbolForOffsetOfRecord(long offset) {
|
||||
return getSymbolsByOffset().get(offset - 4);
|
||||
|
@ -211,13 +209,13 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Returns the {@link AbstractMsSymbol} for the module as specified by moduleNumber and
|
||||
* actual symbol record offset (which is past the length and symbol type fields).
|
||||
* @param moduleNumber The number ID of the module (1 to {@link #getNumModules()}) for
|
||||
* which to return the list.
|
||||
* actual symbol record offset (which is past the length and symbol type fields)
|
||||
* @param moduleNumber the number ID of the module (1 to {@link #getNumModules()}) for
|
||||
* which to return the list
|
||||
* @param offset the offset of the symbol (beyond length and symbol type fields); this is the
|
||||
* offset value specified by many symbol type records.
|
||||
* @return the symbol group for the module or null if not found.
|
||||
* @throws PdbException Upon moduleNumber out of range or no module information.
|
||||
* offset value specified by many symbol type records
|
||||
* @return the symbol group for the module or null if not found
|
||||
* @throws PdbException upon moduleNumber out of range or no module information
|
||||
*/
|
||||
public AbstractMsSymbol getSymbolForModuleAndOffsetOfRecord(int moduleNumber, long offset)
|
||||
throws PdbException {
|
||||
|
@ -229,41 +227,40 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns list of {@link AbstractSectionContribution} for this Database Interface.
|
||||
* @return List of {@link AbstractSectionContribution}.
|
||||
* Returns list of {@link SectionContribution} for this debug info
|
||||
* @return list of {@link SectionContribution}
|
||||
*/
|
||||
public List<AbstractSectionContribution> getSectionContributionList() {
|
||||
public List<SectionContribution> getSectionContributionList() {
|
||||
return sectionContributionList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of {@link SegmentMapDescription} for this Database Interface.
|
||||
* @return List of {@link SegmentMapDescription}.
|
||||
* Returns list of {@link SegmentMapDescription} for this debug info
|
||||
* @return list of {@link SegmentMapDescription}
|
||||
*/
|
||||
public List<SegmentMapDescription> getSegmentMapList() {
|
||||
return segmentMapList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link SymbolRecords} component for this Database Interface.
|
||||
* @return {@link SymbolRecords} component.
|
||||
* Returns {@link SymbolRecords} component for this debug info
|
||||
* @return {@link SymbolRecords} component
|
||||
*/
|
||||
public SymbolRecords getSymbolRecords() {
|
||||
return symbolRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link GlobalSymbolInformation} component for this Database Interface.
|
||||
* @return {@link GlobalSymbolInformation} component.
|
||||
* Returns {@link GlobalSymbolInformation} component for this debug info
|
||||
* @return {@link GlobalSymbolInformation} component
|
||||
*/
|
||||
public GlobalSymbolInformation getGlobalSymbolInformation() {
|
||||
return globalSymbolInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Public Symbol Information component for
|
||||
* this Database Interface.
|
||||
* @return Public Symbol Information component.
|
||||
* Returns Public Symbol Information component for this debug info
|
||||
* @return Public Symbol Information component
|
||||
*/
|
||||
public PublicSymbolInformation getPublicSymbolInformation() {
|
||||
return publicSymbolInformation;
|
||||
|
@ -273,24 +270,24 @@ public abstract class PdbDebugInfo {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the stream number for the GlobalSymbols component.
|
||||
* @return Stream number.
|
||||
* Returns the stream number for the GlobalSymbols component
|
||||
* @return stream number
|
||||
*/
|
||||
int getGlobalSymbolsHashMaybeStreamNumber() {
|
||||
return streamNumberGlobalStaticSymbolsHashMaybe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream number for the PublicStaticSymbols component.
|
||||
* @return Stream number.
|
||||
* Returns the stream number for the PublicStaticSymbols component
|
||||
* @return stream number
|
||||
*/
|
||||
int getPublicStaticSymbolsHashMaybeStreamNumber() {
|
||||
return streamNumberPublicStaticSymbolsHashMaybe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream number for {@link SymbolRecords} component.
|
||||
* @return Stream number.
|
||||
* Returns the stream number for {@link SymbolRecords} component
|
||||
* @return stream number
|
||||
*/
|
||||
int getSymbolRecordsStreamNumber() {
|
||||
return streamNumberSymbolRecords;
|
||||
|
@ -300,9 +297,9 @@ public abstract class PdbDebugInfo {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Header.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the Header
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected abstract void deserializeHeader(PdbByteReader reader) throws PdbException;
|
||||
|
||||
|
@ -313,64 +310,62 @@ public abstract class PdbDebugInfo {
|
|||
protected abstract int getHeaderLength();
|
||||
|
||||
/**
|
||||
* Deserializes the SubStreams internal to the Database Interface stream.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the SubStreams internal to the debug info stream
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected abstract void deserializeInternalSubstreams(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected abstract void deserializeInternalSubstreams(PdbByteReader reader)
|
||||
throws PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Deserializes the AdditionalSubstreams components.
|
||||
* @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.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the AdditionalSubstreams components
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected abstract void deserializeAdditionalSubstreams(TaskMonitor monitor)
|
||||
protected abstract void deserializeAdditionalSubstreams()
|
||||
throws IOException, PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Deserializes/Processes the appropriate {@link AbstractModuleInformation} flavor.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException upon error parsing a field.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes/processes the appropriate {@link ModuleInformation} flavor
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected abstract void processModuleInformation(PdbByteReader reader, TaskMonitor monitor,
|
||||
boolean skip) throws PdbException, CancelledException;
|
||||
protected abstract void processModuleInformation(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Dumps the Header. This method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the Header. This method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
*/
|
||||
protected abstract void dumpHeader(Writer writer) throws IOException;
|
||||
|
||||
/**
|
||||
* Dumps the Internal Substreams. This method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the Internal Substreams. This method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected abstract void dumpInternalSubstreams(Writer writer) throws IOException;
|
||||
protected abstract void dumpInternalSubstreams(Writer writer)
|
||||
throws IOException, CancelledException;
|
||||
|
||||
//==============================================================================================
|
||||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes/Processes the SectionContributions component.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes/processes the SectionContributions component
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void processSectionContributions(PdbByteReader reader, TaskMonitor monitor,
|
||||
boolean skip) throws PdbException, CancelledException {
|
||||
protected void processSectionContributions(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthSectionContributionSubstream == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -385,8 +380,8 @@ public abstract class PdbDebugInfo {
|
|||
if (version == SCV1400) {
|
||||
//long version2 = substreamReader.parseUnsignedIntVal();
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
AbstractSectionContribution sectionContribution = new SectionContribution1400();
|
||||
pdb.checkCanceled();
|
||||
SectionContribution sectionContribution = new SectionContribution1400();
|
||||
sectionContribution.deserialize(substreamReader);
|
||||
sectionContributionList.add(sectionContribution);
|
||||
}
|
||||
|
@ -394,8 +389,8 @@ public abstract class PdbDebugInfo {
|
|||
else if (version == SCV600) {
|
||||
//long version2 = substreamReader.parseUnsignedIntVal();
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
AbstractSectionContribution sectionContribution = new SectionContribution600();
|
||||
pdb.checkCanceled();
|
||||
SectionContribution sectionContribution = new SectionContribution600();
|
||||
sectionContribution.deserialize(substreamReader);
|
||||
sectionContributionList.add(sectionContribution);
|
||||
}
|
||||
|
@ -403,11 +398,11 @@ public abstract class PdbDebugInfo {
|
|||
//TODO: Don't know when SectionContribution200 is the type to use. Don't know if
|
||||
// this part could be the default of processSectionContribs within
|
||||
// DebugInfo and if the above part (test for SVC600 and SVC1400 would
|
||||
// be the override method for DatabaseInformationNew.
|
||||
// be the override method for PdbNewDebugInfo.
|
||||
else {
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
AbstractSectionContribution sectionContribution = new SectionContribution400();
|
||||
pdb.checkCanceled();
|
||||
SectionContribution sectionContribution = new SectionContribution400();
|
||||
sectionContribution.deserialize(substreamReader);
|
||||
sectionContributionList.add(sectionContribution);
|
||||
}
|
||||
|
@ -415,18 +410,17 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes/Processes the {@link SegmentMapDescription}.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes/processes the {@link SegmentMapDescription}
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
// TODO: unused value numSegLog?
|
||||
// Note: this is SegmentMap or SectionMap (API structs are segment; API code is Section)
|
||||
// Suppress "unused" for numSegLog
|
||||
@SuppressWarnings("unused")
|
||||
protected void processSegmentMap(PdbByteReader reader, TaskMonitor monitor, boolean skip)
|
||||
protected void processSegmentMap(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthSectionMap == 0) {
|
||||
return;
|
||||
|
@ -442,7 +436,7 @@ public abstract class PdbDebugInfo {
|
|||
int numSegLog = substreamReader.parseUnsignedShortVal();
|
||||
// Process records
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
SegmentMapDescription segment = new SegmentMapDescription();
|
||||
segment.deserialize(substreamReader);
|
||||
segmentMapList.add(segment);
|
||||
|
@ -453,14 +447,13 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes/Processes the FileInformation.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException upon error parsing filename.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes/processes the FileInformation
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon error parsing filename
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void processFileInformation(PdbByteReader reader, TaskMonitor monitor, boolean skip)
|
||||
protected void processFileInformation(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthFileInformation == 0) {
|
||||
return;
|
||||
|
@ -484,7 +477,7 @@ public abstract class PdbDebugInfo {
|
|||
int[] count = new int[numInformationModules];
|
||||
int totalCount = 0;
|
||||
for (int moduleIndex = 0; moduleIndex < numInformationModules; moduleIndex++) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
index[moduleIndex] = indicesReader.parseUnsignedShortVal();
|
||||
count[moduleIndex] = countsReader.parseUnsignedShortVal();
|
||||
totalCount += count[moduleIndex];
|
||||
|
@ -497,6 +490,7 @@ public abstract class PdbDebugInfo {
|
|||
PdbByteReader offsetReader = fileInfoReader.getSubPdbByteReader(totalCount * 4);
|
||||
int[] offset = new int[totalCount];
|
||||
for (int moduleIndex = 0; moduleIndex < totalCount; moduleIndex++) {
|
||||
pdb.checkCanceled();
|
||||
offset[moduleIndex] = offsetReader.parseInt();
|
||||
}
|
||||
PdbByteReader namesReader =
|
||||
|
@ -504,8 +498,10 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
int totalRefs = 0;
|
||||
for (int moduleIndex = 0; moduleIndex < numInformationModules; moduleIndex++) {
|
||||
AbstractModuleInformation module = moduleInformationList.get(moduleIndex);
|
||||
pdb.checkCanceled();
|
||||
ModuleInformation module = moduleInformationList.get(moduleIndex);
|
||||
for (int fileIndex = 0; fileIndex < count[moduleIndex]; fileIndex++) {
|
||||
pdb.checkCanceled();
|
||||
int ref = totalRefs + fileIndex;
|
||||
int nameOffset = offset[ref];
|
||||
namesReader.setIndex(nameOffset);
|
||||
|
@ -518,7 +514,7 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Method to parse the filename for the "File Information" section from the
|
||||
* {@link PdbByteReader}.
|
||||
* {@link PdbByteReader}
|
||||
* @param reader the {@link PdbByteReader} from which to parse the data
|
||||
* @return the filename
|
||||
* @throws PdbException upon error parsing the filename
|
||||
|
@ -527,11 +523,11 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Debug method for dumping information from this {@link PdbDebugInfo}-based
|
||||
* instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected void dump(Writer writer) throws IOException, CancelledException, PdbException {
|
||||
writer.write("DebugInfoHeader---------------------------------------------\n");
|
||||
|
@ -546,12 +542,11 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping additional substreams from this
|
||||
* {@link PdbDebugInfo}-based instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* Debug method for dumping additional substreams from this {@link PdbDebugInfo}-based instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected void dumpAdditionalSubstreams(Writer writer)
|
||||
throws IOException, CancelledException, PdbException {
|
||||
|
@ -563,19 +558,22 @@ public abstract class PdbDebugInfo {
|
|||
if (doNewStuff) {
|
||||
dumpSymbols(writer);
|
||||
for (Module module : modules) {
|
||||
pdb.checkCanceled();
|
||||
module.dump(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping module information for all of the {@link AbstractModuleInformation}
|
||||
* modules from this {@link PdbDebugInfo}-based instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* Debug method for dumping module information for all of the {@link ModuleInformation}
|
||||
* modules from this {@link PdbDebugInfo}-based instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dumpModuleInformation(Writer writer) throws IOException {
|
||||
for (AbstractModuleInformation information : moduleInformationList) {
|
||||
protected void dumpModuleInformation(Writer writer) throws IOException, CancelledException {
|
||||
for (ModuleInformation information : moduleInformationList) {
|
||||
pdb.checkCanceled();
|
||||
writer.write(information.dump());
|
||||
writer.write("\n");
|
||||
}
|
||||
|
@ -583,13 +581,14 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Debug method for dumping section contribution for all of the
|
||||
* {@link AbstractSectionContribution} components from this
|
||||
* {@link PdbDebugInfo}-based instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* {@link SectionContribution} components from this {@link PdbDebugInfo}-based instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dumpSectionContributions(Writer writer) throws IOException {
|
||||
for (AbstractSectionContribution contribution : sectionContributionList) {
|
||||
protected void dumpSectionContributions(Writer writer) throws IOException, CancelledException {
|
||||
for (SectionContribution contribution : sectionContributionList) {
|
||||
pdb.checkCanceled();
|
||||
writer.write(contribution.dump());
|
||||
writer.write("\n");
|
||||
}
|
||||
|
@ -597,13 +596,14 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Debug method for dumping segment map information for all of the
|
||||
* {@link SegmentMapDescription} components from this {@link PdbDebugInfo}-based
|
||||
* instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* {@link SegmentMapDescription} components from this {@link PdbDebugInfo}-based instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dumpSegmentMap(Writer writer) throws IOException {
|
||||
protected void dumpSegmentMap(Writer writer) throws IOException, CancelledException {
|
||||
for (SegmentMapDescription description : segmentMapList) {
|
||||
pdb.checkCanceled();
|
||||
writer.write(description.dump());
|
||||
writer.write("\n");
|
||||
}
|
||||
|
@ -612,10 +612,10 @@ public abstract class PdbDebugInfo {
|
|||
//==============================================================================================
|
||||
// NEW STUFF FROM REFACTOR/REWORK (can be duplicative with other stuff)... might be turned off
|
||||
// during development.
|
||||
private void parseModules(TaskMonitor monitor) throws CancelledException {
|
||||
for (AbstractModuleInformation moduleInformation : moduleInformationList) {
|
||||
monitor.checkCanceled();
|
||||
Module module = new Module(pdb, moduleInformation, monitor);
|
||||
private void parseModules() throws CancelledException {
|
||||
for (ModuleInformation moduleInformation : moduleInformationList) {
|
||||
pdb.checkCanceled();
|
||||
Module module = new Module(pdb, moduleInformation);
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return the Module based upon the module number.
|
||||
* Return the Module based upon the module number
|
||||
* @param moduleNum the module number
|
||||
* @return the module
|
||||
*/
|
||||
|
@ -635,28 +635,27 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
// NOTE: Designs are not done regarding possibly iterators for iterating only globals or publics
|
||||
/**
|
||||
* Returns the symbol iterator for general (public and global symbols.
|
||||
* @param monitor monitor for the job
|
||||
* Returns the symbol iterator for general (public and global symbols
|
||||
* @return an iterator over all symbols of the module
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws IOException upon issue reading the stream
|
||||
*/
|
||||
public MsSymbolIterator getSymbolIterator(TaskMonitor monitor)
|
||||
public MsSymbolIterator getSymbolIterator()
|
||||
throws CancelledException, IOException {
|
||||
if (streamNumberSymbolRecords == 0xffff) {
|
||||
return null;
|
||||
}
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumberSymbolRecords, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumberSymbolRecords);
|
||||
MsSymbolIterator iterator = new MsSymbolIterator(pdb, reader);
|
||||
return iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the symbol iterator symbols of the specified module.
|
||||
* Returns the symbol iterator symbols of the specified module
|
||||
* @param moduleNum the module number
|
||||
* @return an iterator over all symbols of the module
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
MsSymbolIterator getSymbolIterator(int moduleNum) throws CancelledException, PdbException {
|
||||
Module module = modules.get(moduleNum);
|
||||
|
@ -664,17 +663,17 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
private void dumpSymbols(Writer writer) throws CancelledException, IOException {
|
||||
// TODO: in GP-2367 (rename/refactor) ticket... put in appropriate monitor
|
||||
MsSymbolIterator iterator = getSymbolIterator(TaskMonitor.DUMMY);
|
||||
MsSymbolIterator iterator = getSymbolIterator();
|
||||
List<AbstractMsSymbol> symbols = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
symbols.add(iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
// This method is temporary. It only exists for ensuring results as we transition processing
|
||||
// mechanisms.
|
||||
private void compareSymbols(TaskMonitor monitor)
|
||||
private void compareSymbols()
|
||||
throws CancelledException, PdbException, IOException {
|
||||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||
if (debugInfo == null) {
|
||||
|
@ -682,9 +681,10 @@ public abstract class PdbDebugInfo {
|
|||
}
|
||||
|
||||
// Compare general symbols
|
||||
MsSymbolIterator iterator = getSymbolIterator(monitor);
|
||||
MsSymbolIterator iterator = getSymbolIterator();
|
||||
List<AbstractMsSymbol> symbols = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
pdb.checkCanceled();
|
||||
symbols.add(iterator.next());
|
||||
}
|
||||
if (symbols.size() != symbolRecords.getSymbolsByOffset().size()) {
|
||||
|
@ -695,6 +695,7 @@ public abstract class PdbDebugInfo {
|
|||
int cnt = 0;
|
||||
for (Map.Entry<Long, AbstractMsSymbol> entry : symbolRecords.getSymbolsByOffset()
|
||||
.entrySet()) {
|
||||
pdb.checkCanceled();
|
||||
AbstractMsSymbol msym = entry.getValue();
|
||||
AbstractMsSymbol lsym = symbols.get(cnt);
|
||||
String mstr = msym.toString();
|
||||
|
@ -709,17 +710,20 @@ public abstract class PdbDebugInfo {
|
|||
|
||||
// Compare module symbols
|
||||
for (int modnum = 0; modnum < numModules(); modnum++) {
|
||||
pdb.checkCanceled();
|
||||
Module module = modules.get(modnum);
|
||||
MsSymbolIterator moduleSymbolsIterator = module.getSymbolIterator();
|
||||
cnt = 0;
|
||||
Map<Long, AbstractMsSymbol> map = symbolRecords.getModuleSymbolsByOffset(modnum);
|
||||
List<Long> keys = new ArrayList<>();
|
||||
for (Map.Entry<Long, AbstractMsSymbol> entry : map.entrySet()) {
|
||||
pdb.checkCanceled();
|
||||
Long key = entry.getKey();
|
||||
keys.add(key);
|
||||
}
|
||||
Collections.sort(keys);
|
||||
for (Long key : keys) {
|
||||
pdb.checkCanceled();
|
||||
AbstractMsSymbol msym = map.get(key);
|
||||
if (!moduleSymbolsIterator.hasNext()) {
|
||||
// Set break-point on next line. Multiple lines here to eliminate Eclipse warning.
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Parser for detecting the appropriate {@link PdbDebugInfo} format for the filename
|
||||
|
@ -44,13 +43,13 @@ public class PdbDebugInfoParser {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Parses information to determine the version of Database Interface to create.
|
||||
* @param pdb {@link AbstractPdb} that owns this Database Interface.
|
||||
* @return {@link PdbDebugInfo} of the appropriate Database Interface or null if
|
||||
* the stream does not have enough information to be parsed.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* Parses information to determine the version of debug info to create
|
||||
* @param pdb {@link AbstractPdb} that owns this debug info
|
||||
* @return {@link PdbDebugInfo} of the appropriate debug info or null if the stream does not
|
||||
* have enough information to be parsed
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error in processing components
|
||||
*/
|
||||
public PdbDebugInfo parse(AbstractPdb pdb) throws IOException, PdbException {
|
||||
PdbDebugInfo debugInfo;
|
||||
|
@ -58,7 +57,7 @@ public class PdbDebugInfoParser {
|
|||
int streamNumber = getStreamNumber();
|
||||
// Only reading 8-bytes - no need for monitor
|
||||
PdbByteReader reader =
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, 8, TaskMonitor.DUMMY);
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, 8);
|
||||
if (reader.getLimit() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -102,8 +101,8 @@ public class PdbDebugInfoParser {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the standard stream number that contains the serialized Database Interface.
|
||||
* @return Stream number that contains the Database Interface.
|
||||
* Returns the standard stream number that contains the serialized debug info
|
||||
* @return stream number that contains the debug info
|
||||
*/
|
||||
protected int getStreamNumber() {
|
||||
return DEBUG_INFO_STREAM_NUMBER;
|
||||
|
|
|
@ -40,8 +40,8 @@ public class PdbLog {
|
|||
* method gives control to the client to be able to turn on/off the messaging output without
|
||||
* having to do conditional checks at each point that one of the messaging methods is called.
|
||||
* @param enable {@code true} to enable logging; {@code false} to disable logging. Initial
|
||||
* state is {@code false}.
|
||||
* @throws IOException upon problem creating a {@link FileWriter}.
|
||||
* state is {@code false}
|
||||
* @throws IOException upon problem creating a {@link FileWriter}
|
||||
* @see #message(String)
|
||||
* @see #message(String, Supplier...)
|
||||
*/
|
||||
|
@ -53,11 +53,11 @@ public class PdbLog {
|
|||
* Outputs a message to the PDB log if messaging has been enable, else ignored. This method
|
||||
* uses a format string and a variable arguments list of lambdas to allow for deferred
|
||||
* processing of the message to output. Thus, when message output is disabled, the client
|
||||
* does not endure as much cost in supplying a message string that is not used.
|
||||
* does not endure as much cost in supplying a message string that is not used
|
||||
* @param format a {@link String} format list as would be used to a printf() function, but
|
||||
* which must only specify {@code %s} {@link String} outputs.
|
||||
* @param suppliers variable number of {@link Supplier}<{@link String}> arguments. The
|
||||
* number must match the number of {@code %s} outputs in the format string.
|
||||
* number must match the number of {@code %s} outputs in the format string
|
||||
* @see #setEnabled(boolean)
|
||||
*/
|
||||
// We know this is @SafeVarags (or SuppressWarnings("unchecked")) on potential
|
||||
|
@ -89,9 +89,9 @@ public class PdbLog {
|
|||
* Outputs a message to the PDB log if messaging has been enable, else ignored. This method
|
||||
* uses a {@link Supplier}<{@link String}> to allow for deferred processing of the message
|
||||
* to output. Thus, when message output is disabled, the client does not endure as much cost
|
||||
* in supplying a message string that is not used.
|
||||
* in supplying a message string that is not used
|
||||
* @param supplier a {@link Supplier}<{@link String}> that supplies a {@link String}
|
||||
* message to be output.
|
||||
* message to be output
|
||||
* @see #setEnabled(boolean)
|
||||
*/
|
||||
public static void message(Supplier<String> supplier) {
|
||||
|
@ -111,8 +111,8 @@ public class PdbLog {
|
|||
}
|
||||
|
||||
/**
|
||||
* Outputs a {@link String} message to the PDB log if messaging has been enable, else ignored.
|
||||
* @param message a {@link String} message to be output.
|
||||
* Outputs a {@link String} message to the PDB log if messaging has been enable, else ignored
|
||||
* @param message a {@link String} message to be output
|
||||
* @see #setEnabled(boolean)
|
||||
*/
|
||||
public static void message(String message) {
|
||||
|
@ -145,17 +145,17 @@ public class PdbLog {
|
|||
// might not have been read, depending on the order of how record sets are read.
|
||||
// TODO: is using PdbLog here. Is that what we intend?
|
||||
/**
|
||||
* Logs fact of record index out of range (detection is performed by caller).
|
||||
* @param tpi the TypeProgramInterface involved.
|
||||
* @param recordNumber the record number to report.
|
||||
* Logs fact of record index out of range (detection is performed by caller)
|
||||
* @param tpi the TypeProgramInterface involved
|
||||
* @param recordNumber the record number to report
|
||||
*/
|
||||
public static void logBadTypeRecordIndex(AbstractTypeProgramInterface tpi, int recordNumber) {
|
||||
public static void logBadTypeRecordIndex(TypeProgramInterface tpi, int recordNumber) {
|
||||
message("Bad requested type record " + recordNumber + ", min: " + tpi.getTypeIndexMin() +
|
||||
", max: " + tpi.getTypeIndexMaxExclusive());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs fact of record index out of range (detection is performed by caller).
|
||||
* Logs fact of record index out of range (detection is performed by caller)
|
||||
* @param type {@link AbstractMsType} found
|
||||
* @param itemRequiredClass class expected
|
||||
*/
|
||||
|
@ -165,7 +165,7 @@ public class PdbLog {
|
|||
}
|
||||
|
||||
/**
|
||||
* Cleans up the class by closing resources.
|
||||
* Cleans up the class by closing resources
|
||||
*/
|
||||
public static void dispose() {
|
||||
try {
|
||||
|
@ -180,8 +180,8 @@ public class PdbLog {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Writer} for logging.
|
||||
* @return a {@link Writer} for for logging.
|
||||
* Returns the {@link Writer} for logging
|
||||
* @return a {@link Writer} for for logging
|
||||
*/
|
||||
private static Writer getWriter() throws IOException {
|
||||
return enabled ? getFileWriter() : getNullWriter();
|
||||
|
@ -189,8 +189,8 @@ public class PdbLog {
|
|||
|
||||
/**
|
||||
* Returns the {@link FileWriter} for the log file. If the file is already open, it is
|
||||
* returned. If not already open, it is opened and previous contents are deleted.
|
||||
* @return a {@link FileWriter} for the log file.
|
||||
* returned. If not already open, it is opened and previous contents are deleted
|
||||
* @return a {@link FileWriter} for the log file
|
||||
*/
|
||||
private static Writer getFileWriter() throws IOException {
|
||||
if (fileWriter == null) {
|
||||
|
@ -210,8 +210,8 @@ public class PdbLog {
|
|||
|
||||
/**
|
||||
* Returns a {@link NullWriter} for the log file when chosen instead of a FileWriter. If
|
||||
* one already exists, it is returned. Otherwise a new one is created.
|
||||
* @return a {@link NullWriter} for the log file.
|
||||
* one already exists, it is returned. Otherwise a new one is created
|
||||
* @return a {@link NullWriter} for the log file
|
||||
*/
|
||||
private static Writer getNullWriter() {
|
||||
if (nullWriter == null) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link PdbDebugInfo} for newer PDB files.
|
||||
|
@ -63,9 +62,9 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link PdbNewDebugInfo}.
|
||||
* @param streamNumber The stream number that contains the {@link PdbNewDebugInfo} data.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link PdbNewDebugInfo}
|
||||
* @param streamNumber the stream number that contains the {@link PdbNewDebugInfo} data
|
||||
*/
|
||||
public PdbNewDebugInfo(AbstractPdb pdb, int streamNumber) {
|
||||
super(pdb, streamNumber);
|
||||
|
@ -73,16 +72,16 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ImageFileMachine} machine type.
|
||||
* @return the machine type.
|
||||
* Returns the {@link ImageFileMachine} machine type
|
||||
* @return the machine type
|
||||
*/
|
||||
public ImageFileMachine getMachineType() {
|
||||
return machineType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DebugData} for this {@link PdbNewDebugInfo}.
|
||||
* @return the {@link DebugData}.
|
||||
* Returns the {@link DebugData} for this {@link PdbNewDebugInfo}
|
||||
* @return the {@link DebugData}
|
||||
*/
|
||||
public DebugData getDebugData() {
|
||||
return debugData;
|
||||
|
@ -133,34 +132,34 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void deserializeInternalSubstreams(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected void deserializeInternalSubstreams(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
processModuleInformation(reader, monitor, false);
|
||||
processSectionContributions(reader, monitor, false);
|
||||
processSegmentMap(reader, monitor, false);
|
||||
processFileInformation(reader, monitor, false);
|
||||
processModuleInformation(reader, false);
|
||||
processSectionContributions(reader, false);
|
||||
processSegmentMap(reader, false);
|
||||
processFileInformation(reader, false);
|
||||
processTypeServerMap(reader, false);
|
||||
//Note that the next two are in reverse order from their length fields in the header.
|
||||
processEditAndContinueInformation(reader, monitor, false);
|
||||
processEditAndContinueInformation(reader, false);
|
||||
//processDebugHeader(reader, false);
|
||||
debugData.deserializeHeader(reader, monitor);
|
||||
debugData.deserializeHeader(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deserializeAdditionalSubstreams(TaskMonitor monitor)
|
||||
protected void deserializeAdditionalSubstreams()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
// TODO: evaluate. I don't think we need GlobalSymbolInformation (hash) or the
|
||||
// PublicSymbolInformation (hash), as they are both are search mechanisms.
|
||||
symbolRecords.deserialize(monitor);
|
||||
globalSymbolInformation.deserialize(getGlobalSymbolsHashMaybeStreamNumber(), monitor);
|
||||
publicSymbolInformation.deserialize(getPublicStaticSymbolsHashMaybeStreamNumber(), monitor);
|
||||
symbolRecords.deserialize();
|
||||
globalSymbolInformation.deserialize(getGlobalSymbolsHashMaybeStreamNumber());
|
||||
publicSymbolInformation.deserialize(getPublicStaticSymbolsHashMaybeStreamNumber());
|
||||
//TODO: Process further information that might be found from ProcessTypeServerMap,
|
||||
// and processEditAndContinueInformation.
|
||||
debugData.deserialize(monitor);
|
||||
debugData.deserialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processModuleInformation(PdbByteReader reader, TaskMonitor monitor, boolean skip)
|
||||
protected void processModuleInformation(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthModuleInformationSubstream == 0) {
|
||||
return;
|
||||
|
@ -172,8 +171,8 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
PdbByteReader substreamReader =
|
||||
reader.getSubPdbByteReader(lengthModuleInformationSubstream);
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
AbstractModuleInformation moduleInformation = new ModuleInformation600(pdb);
|
||||
pdb.checkCanceled();
|
||||
ModuleInformation moduleInformation = new ModuleInformation600(pdb);
|
||||
moduleInformation.deserialize(substreamReader);
|
||||
moduleInformationList.add(moduleInformation);
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void dumpInternalSubstreams(Writer writer) throws IOException {
|
||||
protected void dumpInternalSubstreams(Writer writer) throws IOException, CancelledException {
|
||||
writer.write("ModuleInformationList---------------------------------------\n");
|
||||
dumpModuleInformation(writer);
|
||||
writer.write("\nEnd ModuleInformationList-----------------------------------\n");
|
||||
|
@ -251,10 +250,10 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
//==============================================================================================
|
||||
//TODO: Find examples that exercise this.
|
||||
/**
|
||||
* Deserializes/Processes the TypeServerMap.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes/processes the TypeServerMap
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
@SuppressWarnings("unused") // substreamReader
|
||||
protected void processTypeServerMap(PdbByteReader reader, boolean skip) throws PdbException {
|
||||
|
@ -270,16 +269,15 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes/Processes the EditAndContinueInformation.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @param skip Skip over the data in the {@link PdbByteReader}.
|
||||
* @throws PdbException upon error parsing a name or unexpected data.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes/processes the EditAndContinueInformation
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @param skip skip over the data in the {@link PdbByteReader}
|
||||
* @throws PdbException upon error parsing a name or unexpected data
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@SuppressWarnings("unused") // hashVal
|
||||
protected void processEditAndContinueInformation(PdbByteReader reader, TaskMonitor monitor,
|
||||
boolean skip) throws PdbException, CancelledException {
|
||||
protected void processEditAndContinueInformation(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthEditAndContinueSubstream == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -312,7 +310,7 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
int count = tableSize;
|
||||
int realEntryCount = 0;
|
||||
while (--count >= 0) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int offset = substreamReader.parseInt();
|
||||
bufferReader.setIndex(offset);
|
||||
String name = bufferReader.parseNullTerminatedString(
|
||||
|
@ -336,8 +334,8 @@ public class PdbNewDebugInfo extends PdbDebugInfo {
|
|||
|
||||
/**
|
||||
* Dumps the EditAndContinueNameList. This package-protected method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
*/
|
||||
protected void dumpEditAndContinueNameList(Writer writer) throws IOException {
|
||||
for (String name : editAndContinueNameList) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link PdbDebugInfo} for older PDB files.
|
||||
|
@ -34,9 +33,9 @@ public class PdbOldDebugInfo extends PdbDebugInfo {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link PdbOldDebugInfo}.
|
||||
* @param streamNumber The number of the stream that contains the {@link PdbOldDebugInfo}.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link PdbOldDebugInfo}
|
||||
* @param streamNumber the number of the stream that contains the {@link PdbOldDebugInfo}
|
||||
*/
|
||||
public PdbOldDebugInfo(AbstractPdb pdb, int streamNumber) {
|
||||
super(pdb, streamNumber);
|
||||
|
@ -62,28 +61,28 @@ public class PdbOldDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void deserializeInternalSubstreams(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected void deserializeInternalSubstreams(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
processModuleInformation(reader, monitor, false);
|
||||
processSectionContributions(reader, monitor, false);
|
||||
processSegmentMap(reader, monitor, false);
|
||||
processFileInformation(reader, monitor, false);
|
||||
processModuleInformation(reader, false);
|
||||
processSectionContributions(reader, false);
|
||||
processSegmentMap(reader, false);
|
||||
processFileInformation(reader, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deserializeAdditionalSubstreams(TaskMonitor monitor)
|
||||
protected void deserializeAdditionalSubstreams()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
// TODO: evaluate. I don't think we need GlobalSymbolInformation (hash) or the
|
||||
// PublicSymbolInformation (hash), as they are both are search mechanisms.
|
||||
symbolRecords.deserialize(monitor);
|
||||
globalSymbolInformation.deserialize(getGlobalSymbolsHashMaybeStreamNumber(), monitor);
|
||||
publicSymbolInformation.deserialize(getPublicStaticSymbolsHashMaybeStreamNumber(), monitor);
|
||||
symbolRecords.deserialize();
|
||||
globalSymbolInformation.deserialize(getGlobalSymbolsHashMaybeStreamNumber());
|
||||
publicSymbolInformation.deserialize(getPublicStaticSymbolsHashMaybeStreamNumber());
|
||||
//TODO: SectionContributions has information about code sections and refers to
|
||||
// debug streams for each.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processModuleInformation(PdbByteReader reader, TaskMonitor monitor, boolean skip)
|
||||
protected void processModuleInformation(PdbByteReader reader, boolean skip)
|
||||
throws PdbException, CancelledException {
|
||||
if (lengthModuleInformationSubstream == 0) {
|
||||
return;
|
||||
|
@ -95,8 +94,8 @@ public class PdbOldDebugInfo extends PdbDebugInfo {
|
|||
PdbByteReader substreamReader =
|
||||
reader.getSubPdbByteReader(lengthModuleInformationSubstream);
|
||||
while (substreamReader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
AbstractModuleInformation moduleInformation = new ModuleInformation500(pdb);
|
||||
pdb.checkCanceled();
|
||||
ModuleInformation moduleInformation = new ModuleInformation500(pdb);
|
||||
moduleInformation.deserialize(substreamReader);
|
||||
moduleInformationList.add(moduleInformation);
|
||||
}
|
||||
|
@ -129,7 +128,7 @@ public class PdbOldDebugInfo extends PdbDebugInfo {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void dumpInternalSubstreams(Writer writer) throws IOException {
|
||||
protected void dumpInternalSubstreams(Writer writer) throws IOException, CancelledException {
|
||||
writer.write("ModuleInformationList---------------------------------------\n");
|
||||
dumpModuleInformation(writer);
|
||||
writer.write("\nEnd ModuleInformationList-----------------------------------\n");
|
||||
|
|
|
@ -18,7 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.AbstractMsf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.MsfParser;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -43,16 +43,16 @@ public class PdbParser {
|
|||
/**
|
||||
* Static method to open a PDB file, determine its version, and return an {@link AbstractPdb}
|
||||
* appropriate for that version; it will not have been deserialized. The main method
|
||||
* to deserialize it is {@link AbstractPdb#deserialize(TaskMonitor monitor)}; the method
|
||||
* to deserialize it is {@link AbstractPdb#deserialize()}; the method
|
||||
* used to deserialize its main identifiers (signature, age, guid (if available)) is
|
||||
* {@link AbstractPdb#deserializeIdentifiersOnly(TaskMonitor monitor)}.
|
||||
* @param filename {@link String} pathname of the PDB file to parse.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return {@link AbstractPdb} class object for the file.
|
||||
* @throws IOException on file I/O issues.
|
||||
* @throws PdbException on parsing issues.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* {@link AbstractPdb#deserializeIdentifiersOnly(TaskMonitor monitor)}
|
||||
* @param filename {@link String} pathname of the PDB file to parse
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation
|
||||
* @return {@link AbstractPdb} class object for the file
|
||||
* @throws IOException on file I/O issues
|
||||
* @throws PdbException on parsing issues
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public static AbstractPdb parse(String filename, PdbReaderOptions pdbOptions,
|
||||
TaskMonitor monitor) throws IOException, PdbException, CancelledException {
|
||||
|
@ -62,7 +62,7 @@ public class PdbParser {
|
|||
|
||||
// Do not do a try with resources here, as the msf must live within the PDB that is
|
||||
// created below.
|
||||
AbstractMsf msf = MsfParser.parse(filename, pdbOptions, monitor);
|
||||
Msf msf = MsfParser.parse(filename, pdbOptions, monitor);
|
||||
|
||||
int versionNumber = AbstractPdb.deserializeVersionNumber(msf, monitor);
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.io.Writer;
|
|||
import java.util.*;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents Public Symbol Information component of a PDB file. This class is only
|
||||
|
@ -56,56 +55,56 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdbIn {@link AbstractPdb} that owns the Public Symbol Information to process.
|
||||
* Constructor
|
||||
* @param pdbIn {@link AbstractPdb} that owns the Public Symbol Information to process
|
||||
*/
|
||||
public PublicSymbolInformation(AbstractPdb pdbIn) {
|
||||
super(pdbIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of thunks in the thunk table.
|
||||
* @return the number of thunks.
|
||||
* Returns the number of thunks in the thunk table
|
||||
* @return the number of thunks
|
||||
*/
|
||||
public int getNumThunks() {
|
||||
return numThunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the section within which the thunk table is located.
|
||||
* @return the section of the thunk table.
|
||||
* Returns the section within which the thunk table is located
|
||||
* @return the section of the thunk table
|
||||
*/
|
||||
public int getThunkTableSection() {
|
||||
return iSectionThunkTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the thunk table within the section it is located.
|
||||
* @return the offset of the thunk table.
|
||||
* Returns the offset of the thunk table within the section it is located
|
||||
* @return the offset of the thunk table
|
||||
*/
|
||||
public int getThunkTableOffset() {
|
||||
return offsetThunkTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of each thunk in the thunk table.
|
||||
* @return the size of a thunk.
|
||||
* Returns the size of each thunk in the thunk table
|
||||
* @return the size of a thunk
|
||||
*/
|
||||
public int getThunkSize() {
|
||||
return thunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the overall length of the thunk table.
|
||||
* @return the thunk table length.
|
||||
* Returns the overall length of the thunk table
|
||||
* @return the thunk table length
|
||||
*/
|
||||
public int getThunkTableLength() {
|
||||
return thunkTableLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of sections recorded for the program.
|
||||
* @return the number of sections.
|
||||
* Returns the number of sections recorded for the program
|
||||
* @return the number of sections
|
||||
*/
|
||||
public int getNumSections() {
|
||||
return numSections;
|
||||
|
@ -113,7 +112,7 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
|
||||
/**
|
||||
* Returns the Offsets of symbols within the symbol table gotten from the address map. These
|
||||
* offsets to point to the size field of the symbols in the symbol table.
|
||||
* offsets to point to the size field of the symbols in the symbol table
|
||||
* @return offsets
|
||||
*/
|
||||
public List<Long> getAddressMapSymbolOffsets() {
|
||||
|
@ -124,31 +123,30 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserialize the {@link PublicSymbolInformation} from the appropriate stream in the Pdb.
|
||||
* @param streamNumber the stream number containing the information to deserialize.
|
||||
* @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.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserialize the {@link PublicSymbolInformation} from the appropriate stream in the Pdb
|
||||
* @param streamNumber the stream number containing the information to deserialize
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@Override
|
||||
void deserialize(int streamNumber, TaskMonitor monitor)
|
||||
void deserialize(int streamNumber)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
super.deserialize(streamNumber, monitor);
|
||||
super.deserialize(streamNumber);
|
||||
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
|
||||
deserializePubHeader(reader);
|
||||
|
||||
PdbByteReader hashReader = reader.getSubPdbByteReader(symbolHashLength);
|
||||
deserializeHashTable(hashReader, monitor);
|
||||
deserializeHashTable(hashReader);
|
||||
|
||||
PdbByteReader addressMapReader = reader.getSubPdbByteReader(addressMapLength);
|
||||
deserializeAddressMap(addressMapReader, monitor);
|
||||
deserializeAddressMap(addressMapReader);
|
||||
|
||||
PdbByteReader thunkMapReader = reader.getSubPdbByteReader(thunkMapLength);
|
||||
deserializeThunkMap(thunkMapReader, monitor);
|
||||
deserializeThunkMap(thunkMapReader);
|
||||
|
||||
/*
|
||||
* See note in {@link #deserializePubHeader(PdbByteReader)} regarding spurious data
|
||||
|
@ -161,19 +159,20 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
numSections = sectionMapLength / 8;
|
||||
PdbByteReader sectionMapReader = reader.getSubPdbByteReader(sectionMapLength);
|
||||
deserializeSectionMap(sectionMapReader, monitor);
|
||||
deserializeSectionMap(sectionMapReader);
|
||||
|
||||
// Organize the information
|
||||
generateSymbolsList(monitor);
|
||||
generateSymbolsList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping information from this {@link PublicSymbolInformation}.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}.
|
||||
* Debug method for dumping information from this {@link PublicSymbolInformation}
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon IOException writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@Override
|
||||
void dump(Writer writer) throws IOException {
|
||||
void dump(Writer writer) throws IOException, CancelledException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("PublicSymbolInformation-------------------------------------\n");
|
||||
dumpPubHeader(builder);
|
||||
|
@ -193,23 +192,22 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
// Private Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Address Map for these public symbols.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Address Map for these public symbols
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeAddressMap(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeAddressMap(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
addressMapSymbolOffsets.add((long) reader.parseInt());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping Address Map information from this {@link AbstractSymbolInformation}.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping Address Map information from this {@link AbstractSymbolInformation}
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
*/
|
||||
private void dumpAddressMap(StringBuilder builder) {
|
||||
builder.append("AddressMapSymbolOffsets-------------------------------------\n");
|
||||
|
@ -222,17 +220,16 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes the Thunk Map for these public symbols.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Thunk Map for these public symbols
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeThunkMap(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeThunkMap(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
int count = 0;
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int targetOffset = reader.parseInt();
|
||||
int mapTableOffset = count * thunkSize + offsetThunkTable;
|
||||
thunkTargetOffsetsByTableOffset.put(mapTableOffset, targetOffset);
|
||||
|
@ -240,8 +237,8 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping Thunk Map information from this {@link AbstractSymbolInformation}.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping Thunk Map information from this {@link AbstractSymbolInformation}
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
*/
|
||||
private void dumpThunkMap(StringBuilder builder) {
|
||||
builder.append("ThunkMap----------------------------------------------------\n");
|
||||
|
@ -254,16 +251,15 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes the Section Map for these public symbols.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Section Map for these public symbols
|
||||
* @param reader {@link PdbByteReader} containing the data buffer to process
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void deserializeSectionMap(PdbByteReader reader, TaskMonitor monitor)
|
||||
private void deserializeSectionMap(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
int offset = reader.parseInt();
|
||||
int section = reader.parseUnsignedShortVal();
|
||||
reader.skip(2); // padding
|
||||
|
@ -272,22 +268,24 @@ public class PublicSymbolInformation extends AbstractSymbolInformation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping Section Map information from this {@link AbstractSymbolInformation}.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping Section Map information from this {@link AbstractSymbolInformation}
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void dumpSectionMap(StringBuilder builder) {
|
||||
private void dumpSectionMap(StringBuilder builder) throws CancelledException {
|
||||
builder.append("SectionMap--------------------------------------------------\n");
|
||||
builder.append(
|
||||
"numAbsoluteOffsetsBySectionNumber: " + absoluteOffsetsBySectionNumber.size() + "\n");
|
||||
for (Map.Entry<Integer, Integer> entry : absoluteOffsetsBySectionNumber.entrySet()) {
|
||||
pdb.checkCanceled();
|
||||
builder.append(String.format("0X%08X 0X%08X\n", entry.getKey(), entry.getValue()));
|
||||
}
|
||||
builder.append("\nEnd SectionMap----------------------------------------------\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping the {@link PublicSymbolInformation} header.
|
||||
* @param builder {@link StringBuilder} to which to dump the information.
|
||||
* Debug method for dumping the {@link PublicSymbolInformation} header
|
||||
* @param builder {@link StringBuilder} to which to dump the information
|
||||
*/
|
||||
private void dumpPubHeader(StringBuilder builder) {
|
||||
builder.append("PublicSymbolInformationHeader-------------------------------\n");
|
||||
|
|
|
@ -22,7 +22,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
* We have intended to implement according to the Microsoft PDB API (source); see the API for
|
||||
* truth.
|
||||
*/
|
||||
public abstract class AbstractSectionContribution {
|
||||
public abstract class SectionContribution {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
|
@ -41,7 +41,7 @@ public abstract class AbstractSectionContribution {
|
|||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
public AbstractSectionContribution() {
|
||||
public SectionContribution() {
|
||||
}
|
||||
|
||||
public int getSection() {
|
||||
|
@ -69,15 +69,15 @@ public abstract class AbstractSectionContribution {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Section Contribution.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the Section Contribution
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
abstract void deserialize(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Dumps the SectionContribution. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the SectionContribution. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
abstract String dumpInternals();
|
||||
|
||||
|
@ -85,8 +85,8 @@ public abstract class AbstractSectionContribution {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Dumps the Section Contribution. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the Section Contribution. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
String dump() {
|
||||
StringBuilder builder = new StringBuilder();
|
|
@ -16,16 +16,15 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractSectionContribution} for Microsoft v14.00 PDB.
|
||||
* This class is the version of {@link SectionContribution} for Microsoft v14.00 PDB.
|
||||
*/
|
||||
public class SectionContribution1400 extends AbstractSectionContribution {
|
||||
public class SectionContribution1400 extends SectionContribution {
|
||||
|
||||
//==============================================================================================
|
||||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserialize(PdbByteReader reader) throws PdbException {
|
||||
//System.out.println(reader.dump(0x200));
|
||||
isect = reader.parseUnsignedShortVal();
|
||||
reader.parseBytes(2); // I think there is padding here.
|
||||
offset = reader.parseInt();
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractSectionContribution} for Microsoft v2.00 PDB.
|
||||
* This class is the version of {@link SectionContribution} for Microsoft v2.00 PDB.
|
||||
*/
|
||||
public class SectionContribution200 extends AbstractSectionContribution {
|
||||
public class SectionContribution200 extends SectionContribution {
|
||||
|
||||
//==============================================================================================
|
||||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserialize(PdbByteReader reader) throws PdbException {
|
||||
//System.out.println(reader.dump());
|
||||
isect = reader.parseUnsignedShortVal();
|
||||
offset = reader.parseInt();
|
||||
length = reader.parseInt();
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractSectionContribution} for Microsoft v4.00 PDB.
|
||||
* This class is the version of {@link SectionContribution} for Microsoft v4.00 PDB.
|
||||
*/
|
||||
public class SectionContribution400 extends AbstractSectionContribution {
|
||||
public class SectionContribution400 extends SectionContribution {
|
||||
|
||||
//==============================================================================================
|
||||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserialize(PdbByteReader reader) throws PdbException {
|
||||
//System.out.println(reader.dump(0x200));
|
||||
isect = reader.parseUnsignedShortVal();
|
||||
reader.parseBytes(2); // I think there is padding here.
|
||||
offset = reader.parseInt();
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractSectionContribution} for Microsoft v6.00 PDB.
|
||||
* This class is the version of {@link SectionContribution} for Microsoft v6.00 PDB.
|
||||
*/
|
||||
public class SectionContribution600 extends AbstractSectionContribution {
|
||||
public class SectionContribution600 extends SectionContribution {
|
||||
|
||||
//==============================================================================================
|
||||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
@Override
|
||||
void deserialize(PdbByteReader reader) throws PdbException {
|
||||
//System.out.println(reader.dump(0x200));
|
||||
isect = reader.parseUnsignedShortVal();
|
||||
reader.parseBytes(2); // I think there is padding here.
|
||||
offset = reader.parseInt();
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.*;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents Symbol Records component of a PDB file. This class is only
|
||||
|
@ -37,8 +36,8 @@ public class SymbolRecords {
|
|||
private List<Map<Long, AbstractMsSymbol>> moduleSymbolsByOffset = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} to which the {@link SymbolRecords} belong.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} to which the {@link SymbolRecords} belong
|
||||
*/
|
||||
public SymbolRecords(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
|
@ -46,38 +45,37 @@ public class SymbolRecords {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the list of symbols.
|
||||
* Returns the list of symbols
|
||||
* @return {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
||||
* symbols.
|
||||
* symbols
|
||||
*/
|
||||
protected Map<Long, AbstractMsSymbol> getSymbolsByOffset() {
|
||||
return symbolsByOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer-offset-to-symbol map for the module as specified by moduleNumber.
|
||||
* @param moduleNumber The number ID of the module for which to return the list.
|
||||
* Returns the buffer-offset-to-symbol map for the module as specified by moduleNumber
|
||||
* @param moduleNumber the number ID of the module for which to return the list
|
||||
* @return {@link Map}<{@link Long},{@link AbstractMsSymbol}> of buffer offsets to
|
||||
* symbols for the specified module.
|
||||
* symbols for the specified module
|
||||
*/
|
||||
protected Map<Long, AbstractMsSymbol> getModuleSymbolsByOffset(int moduleNumber) {
|
||||
return moduleSymbolsByOffset.get(moduleNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the {@link SymbolRecords} from the stream noted in the DBI header.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* Deserializes the {@link SymbolRecords} from the stream noted in the DBI header
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException Upon not enough data left to parse
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserialize(TaskMonitor monitor) throws IOException, PdbException, CancelledException {
|
||||
processSymbols(monitor);
|
||||
processModuleSymbols(monitor);
|
||||
void deserialize() throws IOException, PdbException, CancelledException {
|
||||
processSymbols();
|
||||
processModuleSymbols();
|
||||
}
|
||||
|
||||
private void processSymbols(TaskMonitor monitor)
|
||||
private void processSymbols()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||
if (debugInfo == null) {
|
||||
|
@ -87,14 +85,14 @@ public class SymbolRecords {
|
|||
if (streamNumber <= 0) {
|
||||
return;
|
||||
}
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
symbolsByOffset = deserializeSymbolRecords(pdb, reader, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
symbolsByOffset = deserializeSymbolRecords(pdb, reader);
|
||||
}
|
||||
|
||||
// Could split this method up into separate methods: one for module symbols and the other for
|
||||
// Lines processing. Note: would be processing streams more than once; lines would need to
|
||||
// skip over the symbols.
|
||||
private void processModuleSymbols(TaskMonitor monitor)
|
||||
private void processModuleSymbols()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
// cvSignature:
|
||||
// >64K = C6
|
||||
|
@ -114,15 +112,15 @@ public class SymbolRecords {
|
|||
return;
|
||||
}
|
||||
|
||||
for (AbstractModuleInformation module : debugInfo.moduleInformationList) {
|
||||
monitor.checkCanceled();
|
||||
for (ModuleInformation module : debugInfo.moduleInformationList) {
|
||||
pdb.checkCanceled();
|
||||
int streamNumber = module.getStreamNumberDebugInformation();
|
||||
if (streamNumber == 0xffff) {
|
||||
moduleSymbolsByOffset.add(new TreeMap<>());
|
||||
continue;
|
||||
}
|
||||
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
|
||||
int sizeSymbolsSection = module.getSizeLocalSymbolsDebugInformation();
|
||||
PdbByteReader symbolsReader = reader.getSubPdbByteReader(sizeSymbolsSection);
|
||||
|
@ -152,7 +150,7 @@ public class SymbolRecords {
|
|||
}
|
||||
|
||||
Map<Long, AbstractMsSymbol> oneModuleSymbolsByOffset =
|
||||
deserializeSymbolRecords(pdb, symbolsReader, monitor);
|
||||
deserializeSymbolRecords(pdb, symbolsReader);
|
||||
moduleSymbolsByOffset.add(oneModuleSymbolsByOffset);
|
||||
}
|
||||
}
|
||||
|
@ -163,18 +161,17 @@ public class SymbolRecords {
|
|||
* 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
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public static Map<Long, AbstractMsSymbol> deserializeSymbolRecords(AbstractPdb pdb,
|
||||
PdbByteReader reader, TaskMonitor monitor) throws PdbException, CancelledException {
|
||||
PdbByteReader reader) throws PdbException, CancelledException {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
//System.out.println(reader.dump(0x400));
|
||||
Map<Long, AbstractMsSymbol> mySymbolsByOffset = new TreeMap<>();
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
|
||||
// Including length in byte array for alignment purposes.
|
||||
int offset = reader.getIndex();
|
||||
|
@ -185,14 +182,16 @@ public class SymbolRecords {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method for dumping information from this Symbol Records instance.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}
|
||||
* Debug method for dumping information from this Symbol Records instance
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dump(Writer writer) throws IOException {
|
||||
protected void dump(Writer writer) throws IOException, CancelledException {
|
||||
writer.write("SymbolRecords-----------------------------------------------\n");
|
||||
dumpSymbolMap(symbolsByOffset, writer);
|
||||
for (int i = 0; i < moduleSymbolsByOffset.size(); i++) {
|
||||
pdb.checkCanceled();
|
||||
Map<Long, AbstractMsSymbol> map = moduleSymbolsByOffset.get(i);
|
||||
if (map != null) {
|
||||
writer.write("Module(" + i + ") List:\n");
|
||||
|
@ -204,14 +203,16 @@ public class SymbolRecords {
|
|||
|
||||
/**
|
||||
* Debug method for dumping the symbols from a symbol map
|
||||
* @param mySymbolsByOffset the {@link Map}<{@link Long},{@link AbstractMsSymbol}> to dump.
|
||||
* @param writer {@link Writer} to which to dump the information.
|
||||
* @throws IOException Upon IOException writing to the {@link Writer}
|
||||
* @param mySymbolsByOffset the {@link Map}<{@link Long},{@link AbstractMsSymbol}> to dump
|
||||
* @param writer {@link Writer} to which to dump the information
|
||||
* @throws IOException upon issue writing to the {@link Writer}
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void dumpSymbolMap(Map<Long, AbstractMsSymbol> mySymbolsByOffset, Writer writer)
|
||||
throws IOException {
|
||||
throws IOException, CancelledException {
|
||||
writer.write("SymbolMap---------------------------------------------------");
|
||||
for (Map.Entry<Long, AbstractMsSymbol> entry : mySymbolsByOffset.entrySet()) {
|
||||
pdb.checkCanceled();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("\n------------------------------------------------------------\n");
|
||||
builder.append(String.format("Offset: 0X%08X\n", entry.getKey()));
|
||||
|
|
|
@ -31,7 +31,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
* We have intended to implement according to the Microsoft PDB API (source); see the API for
|
||||
* truth.
|
||||
*/
|
||||
public abstract class AbstractTypeProgramInterface implements TPI {
|
||||
public abstract class TypeProgramInterface implements TPI {
|
||||
|
||||
public static final int STREAM_NUMBER_SIZE = 2;
|
||||
|
||||
|
@ -63,13 +63,12 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param recordCategory the RecordCategory of these records.
|
||||
* @param streamNumber The stream number that contains the
|
||||
* {@link AbstractTypeProgramInterface} data.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param recordCategory the RecordCategory of these records
|
||||
* @param streamNumber the stream number that contains the {@link TypeProgramInterface} data
|
||||
*/
|
||||
public AbstractTypeProgramInterface(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
public TypeProgramInterface(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
int streamNumber) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
this.pdb = pdb;
|
||||
|
@ -79,28 +78,28 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes needed to store a {@link AbstractTypeProgramInterface}
|
||||
* version number.
|
||||
* @return The number of bytes read from the bytes array.
|
||||
* Returns the number of bytes needed to store a {@link TypeProgramInterface}
|
||||
* version number
|
||||
* @return the number of bytes read from the bytes array
|
||||
*/
|
||||
static int getVersionNumberSize() {
|
||||
return VERSION_NUMBER_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes Version Number of the {@link AbstractTypeProgramInterface} from the
|
||||
* {@link PdbByteReader}.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize.
|
||||
* @return Version number.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes Version Number of the {@link TypeProgramInterface} from the
|
||||
* {@link PdbByteReader}
|
||||
* @param reader {@link PdbByteReader} from which to deserialize
|
||||
* @return version number
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
static int deserializeVersionNumber(PdbByteReader reader) throws PdbException {
|
||||
return reader.parseInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TypeIndexMin.
|
||||
* @return The TypeIndexMin value from the header.
|
||||
* Returns the TypeIndexMin
|
||||
* @return the TypeIndexMin value from the header
|
||||
*/
|
||||
@Override
|
||||
public int getTypeIndexMin() {
|
||||
|
@ -108,8 +107,8 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the TypeIndexMaxExclusive.
|
||||
* @return TypeIndexMaxExclusive value from the header.
|
||||
* Returns the TypeIndexMaxExclusive
|
||||
* @return TypeIndexMaxExclusive value from the header
|
||||
*/
|
||||
@Override
|
||||
public int getTypeIndexMaxExclusive() {
|
||||
|
@ -118,9 +117,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
|
||||
/**
|
||||
* Retrieves the {@link AbstractMsType} record indicated by the recordNumber. The record must
|
||||
* already have been parsed and inserted into the list.
|
||||
* @param recordNumber Record number to look up.
|
||||
* @return {@link AbstractMsType} pertaining to the record number.
|
||||
* already have been parsed and inserted into the list
|
||||
* @param recordNumber Rrcord number to look up
|
||||
* @return {@link AbstractMsType} pertaining to the record number
|
||||
*/
|
||||
@Override
|
||||
public AbstractMsType getRecord(int recordNumber) {
|
||||
|
@ -147,20 +146,19 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes this {@link AbstractTypeProgramInterface}.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return Version number of the {@link AbstractTypeProgramInterface}.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes this {@link TypeProgramInterface}
|
||||
* @return version number of the {@link TypeProgramInterface}
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
int deserialize(TaskMonitor monitor) throws IOException, PdbException, CancelledException {
|
||||
int deserialize() throws IOException, PdbException, CancelledException {
|
||||
if (pdb.getMsf() == null) {
|
||||
// Should only be null dummy PDBs used for testing.
|
||||
throw new PdbException("Unexpected null MSF.");
|
||||
}
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNumber);
|
||||
|
||||
deserializeHeader(reader);
|
||||
|
||||
|
@ -169,15 +167,15 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// we have this commented out.
|
||||
//hash.deserializeHashStreams(monitor);
|
||||
|
||||
deserializeTypeRecords(reader, monitor);
|
||||
deserializeTypeRecords(reader);
|
||||
|
||||
return versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps this class. This package-protected method is for debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps this class. This package-protected method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
*/
|
||||
void dump(Writer writer) throws IOException {
|
||||
writer.write("TypeProgramInterfaceHeader----------------------------------\n");
|
||||
|
@ -190,14 +188,16 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a basic object.
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* Note: not all values of this class get initialized by this method.
|
||||
* @param pdb {@link AbstractPdb} that owns this this class.
|
||||
* @param typeIndexMin The IndexMin to set/use.
|
||||
* @param typeIndexMaxExclusive One greater than the MaxIndex to set/use.
|
||||
* <p>
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link TypeProgramInterface}.
|
||||
* <p>
|
||||
* Note: not all values of this class get initialized by this method.
|
||||
* @param pdb {@link AbstractPdb} that owns this this class
|
||||
* @param typeIndexMin the IndexMin to set/use
|
||||
* @param typeIndexMaxExclusive one greater than the MaxIndex to set/use
|
||||
*/
|
||||
AbstractTypeProgramInterface(AbstractPdb pdb, int typeIndexMin, int typeIndexMaxExclusive) {
|
||||
TypeProgramInterface(AbstractPdb pdb, int typeIndexMin, int typeIndexMaxExclusive) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
this.pdb = pdb;
|
||||
this.typeIndexMin = typeIndexMin;
|
||||
|
@ -206,10 +206,10 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a record for a particular
|
||||
* record number.
|
||||
* @param recordNumber Record number for the {@link AbstractMsType} to be inserted.
|
||||
* @param type {@link AbstractMsType} to be inserted.
|
||||
* @return True if successful.
|
||||
* record number
|
||||
* @param recordNumber record number for the {@link AbstractMsType} to be inserted
|
||||
* @param type {@link AbstractMsType} to be inserted
|
||||
* @return {@code true} if successful
|
||||
*/
|
||||
boolean setRecord(int recordNumber, AbstractMsType type) {
|
||||
if (recordNumber < typeIndexMin) {
|
||||
|
@ -224,9 +224,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to add a record that gets its
|
||||
* record number automatically assigned.
|
||||
* @param type {@link AbstractMsType} to be inserted.
|
||||
* @return Record number assigned.
|
||||
* record number automatically assigned
|
||||
* @param type {@link AbstractMsType} to be inserted
|
||||
* @return record number assigned
|
||||
*/
|
||||
int addRecord(AbstractMsType type) {
|
||||
int newRecordNum = typeList.size() + typeIndexMin;
|
||||
|
@ -238,16 +238,16 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Header of this class.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the Header of this class
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected abstract void deserializeHeader(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Dumps the Header. This method is for debugging only.
|
||||
* @param writer {@link Writer} to which to dump the header.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the Header. This method is for debugging only
|
||||
* @param writer {@link Writer} to which to dump the header
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
*/
|
||||
protected abstract void dumpHeader(Writer writer) throws IOException;
|
||||
|
||||
|
@ -255,19 +255,18 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Deserializes the Type Records of this class.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Deserializes the Type Records of this class
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void deserializeTypeRecords(PdbByteReader reader, TaskMonitor monitor)
|
||||
protected void deserializeTypeRecords(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
int recordLength;
|
||||
int recordNumber = typeIndexMin;
|
||||
|
||||
while (reader.hasMore()) {
|
||||
monitor.checkCanceled();
|
||||
pdb.checkCanceled();
|
||||
|
||||
recordLength = reader.parseUnsignedShortVal();
|
||||
PdbByteReader recordReader = reader.getSubPdbByteReader(recordLength);
|
||||
|
@ -292,9 +291,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
//TODO: more to do for outputting individual records (might want a toString or dump method
|
||||
// on each).
|
||||
/**
|
||||
* Dumps the Type Records. This method is for debugging only.
|
||||
* @param writer {@link Writer} to which to dump the records.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
* Dumps the Type Records. This method is for debugging only
|
||||
* @param writer {@link Writer} to which to dump the records
|
||||
* @throws IOException on issue writing to the {@link Writer}
|
||||
*/
|
||||
protected void dumpTypeRecords(Writer writer) throws IOException {
|
||||
int recordNum = typeIndexMin;
|
||||
|
@ -338,9 +337,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
private List<TiOff> tiOffs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Deserializes the {@link TypeProgramInterfaceHash}.
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the {@link TypeProgramInterfaceHash}
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected void deserializeHeader800(PdbByteReader reader) throws PdbException {
|
||||
hashStreamNumber = reader.parseUnsignedShortVal();
|
||||
|
@ -356,11 +355,11 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deserializes the {@link TypeProgramInterfaceHash}.
|
||||
* @param hashStreamNumberParam Stream number of the hash.
|
||||
* @param typeIndexMinParam The IndexMin to set/use.
|
||||
* @param typeIndexMaxExclusiveParam One greater than the MaxIndex to set/use.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the {@link TypeProgramInterfaceHash}
|
||||
* @param hashStreamNumberParam stream number of the hash
|
||||
* @param typeIndexMinParam the IndexMin to set/use
|
||||
* @param typeIndexMaxExclusiveParam one greater than the MaxIndex to set/use
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected void initHeader200500(int hashStreamNumberParam, int typeIndexMinParam,
|
||||
int typeIndexMaxExclusiveParam) throws PdbException {
|
||||
|
@ -380,11 +379,11 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
// Suppress "unused" for hashBuffer, typeInfoOffsetPairsBuffer, hashAdjustmentBuffer
|
||||
/**
|
||||
* *UNDER CONSTRUCTION* Deserializes the Hash Streams...
|
||||
* @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.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* @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
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@SuppressWarnings("unused") // for method unused.
|
||||
protected void deserializeHashStreams(TaskMonitor monitor)
|
||||
|
@ -400,7 +399,7 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
if (hashStreamNumber == 0xffff) {
|
||||
return;
|
||||
}
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(hashStreamNumber, monitor);
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(hashStreamNumber);
|
||||
//System.out.println(reader.dump());
|
||||
|
||||
reader.setIndex(offsetHashVals);
|
||||
|
@ -420,7 +419,7 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
return;
|
||||
}
|
||||
PdbByteReader readerAuxiliary =
|
||||
pdb.getReaderForStreamNumber(hashStreamNumberAuxiliary, monitor);
|
||||
pdb.getReaderForStreamNumber(hashStreamNumberAuxiliary);
|
||||
//readerAuxiliary.dump();
|
||||
}
|
||||
|
||||
|
@ -501,8 +500,8 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dumps the this {@link TypeProgramInterfaceHash}. This method is for debugging only.
|
||||
* @return {@link String} of pretty output.
|
||||
* Dumps the this {@link TypeProgramInterfaceHash}. This method is for debugging only
|
||||
* @return {@link String} of pretty output
|
||||
*/
|
||||
protected String dump() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -543,9 +542,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
|
||||
/**
|
||||
* This method is only intended to be used to create a dummy key for performing
|
||||
* a binary search. That is the reason that an {@code offset} parameter is not
|
||||
* specified. The offset is set to zero.
|
||||
* @param typeIndex The type index to fill into the key.
|
||||
* a binary search. That is the reason that an {@code offset} parameter is not
|
||||
* specified. The offset is set to zero
|
||||
* @param typeIndex the type index to fill into the key
|
||||
*/
|
||||
protected TiOff(int typeIndex) {
|
||||
this.typeIndex = typeIndex;
|
||||
|
@ -573,9 +572,9 @@ public abstract class AbstractTypeProgramInterface implements TPI {
|
|||
private class KeyTiOff extends TiOff {
|
||||
/**
|
||||
* This method is only intended to be used to create a dummy key for performing
|
||||
* a binary search. That is the reason that an {@code offset} parameter is not
|
||||
* specified. The offset is set to zero.
|
||||
* @param typeIndex The type index to fill into the key.
|
||||
* a binary search. That is the reason that an {@code offset} parameter is not
|
||||
* specified. The offset is set to zero
|
||||
* @param typeIndex the type index to fill into the key
|
||||
*/
|
||||
protected KeyTiOff(int typeIndex) {
|
||||
super(typeIndex);
|
|
@ -19,9 +19,9 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractTypeProgramInterface} for Microsoft v2.00 PDB.
|
||||
* This class is the version of {@link TypeProgramInterface} for Microsoft v2.00 PDB.
|
||||
*/
|
||||
public class TypeProgramInterface200 extends AbstractTypeProgramInterface {
|
||||
public class TypeProgramInterface200 extends TypeProgramInterface {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
|
@ -32,10 +32,10 @@ public class TypeProgramInterface200 extends AbstractTypeProgramInterface {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param recordCategory the RecordCategory of these records.
|
||||
* @param streamNumber The stream number that contains the {@link AbstractTypeProgramInterface}.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param recordCategory the RecordCategory of these records
|
||||
* @param streamNumber the stream number that contains the {@link TypeProgramInterface}
|
||||
*/
|
||||
public TypeProgramInterface200(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
int streamNumber) {
|
||||
|
@ -79,12 +79,14 @@ public class TypeProgramInterface200 extends AbstractTypeProgramInterface {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a basic object.
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* Note: not all values are initialized.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param typeIndexMin The IndexMin to set/use.
|
||||
* @param typeIndexMaxExclusive One greater than the MaxIndex to set/use.
|
||||
* <p>
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link TypeProgramInterface}.
|
||||
* <p>
|
||||
* Note: not all values are initialized.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param typeIndexMin the IndexMin to set/use
|
||||
* @param typeIndexMaxExclusive one greater than the MaxIndex to set/use
|
||||
*/
|
||||
TypeProgramInterface200(AbstractPdb pdb, int typeIndexMin, int typeIndexMaxExclusive) {
|
||||
super(pdb, typeIndexMin, typeIndexMaxExclusive);
|
||||
|
|
|
@ -19,9 +19,9 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractTypeProgramInterface} for Microsoft v5.00 PDB.
|
||||
* This class is the version of {@link TypeProgramInterface} for Microsoft v5.00 PDB.
|
||||
*/
|
||||
public class TypeProgramInterface500 extends AbstractTypeProgramInterface {
|
||||
public class TypeProgramInterface500 extends TypeProgramInterface {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
|
@ -32,10 +32,10 @@ public class TypeProgramInterface500 extends AbstractTypeProgramInterface {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param recordCategory the RecordCategory of these records.
|
||||
* @param streamNumber The stream number that contains the {@link AbstractTypeProgramInterface}.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param recordCategory the RecordCategory of these records
|
||||
* @param streamNumber the stream number that contains the {@link TypeProgramInterface}
|
||||
*/
|
||||
public TypeProgramInterface500(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
int streamNumber) {
|
||||
|
@ -77,12 +77,14 @@ public class TypeProgramInterface500 extends AbstractTypeProgramInterface {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a basic object.
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* Note: not all values are initialized.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param typeIndexMin The IndexMin to set/use.
|
||||
* @param typeIndexMaxExclusive One greater than the MaxIndex to set/use.
|
||||
* <p>
|
||||
* Note: not all values are initialized. This is a dummy constructor used to create a dummy
|
||||
* {@link TypeProgramInterface}.
|
||||
* <p>
|
||||
* Note: not all values are initialized.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param typeIndexMin the IndexMin to set/use
|
||||
* @param typeIndexMaxExclusive one greater than the MaxIndex to set/use
|
||||
*/
|
||||
TypeProgramInterface500(AbstractPdb pdb, int typeIndexMin, int typeIndexMaxExclusive) {
|
||||
super(pdb, typeIndexMin, typeIndexMaxExclusive);
|
||||
|
|
|
@ -19,18 +19,18 @@ import java.io.IOException;
|
|||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractTypeProgramInterface} for Microsoft v8.00 PDB.
|
||||
* This class is the version of {@link TypeProgramInterface} for Microsoft v8.00 PDB.
|
||||
*/
|
||||
public class TypeProgramInterface800 extends AbstractTypeProgramInterface {
|
||||
public class TypeProgramInterface800 extends TypeProgramInterface {
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param recordCategory the RecordCategory of these records.
|
||||
* @param streamNumber The stream number that contains the {@link AbstractTypeProgramInterface}.
|
||||
* Constructor
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @param recordCategory the RecordCategory of these records
|
||||
* @param streamNumber the stream number that contains the {@link TypeProgramInterface}
|
||||
*/
|
||||
public TypeProgramInterface800(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
int streamNumber) {
|
||||
|
|
|
@ -18,12 +18,11 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
|
|||
import java.io.IOException;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Parser for detecting the appropriate {@link AbstractTypeProgramInterface} format for the
|
||||
* Parser for detecting the appropriate {@link TypeProgramInterface} format for the
|
||||
* filename given. It then creates and returns the appropriate
|
||||
* {@link AbstractTypeProgramInterface} object.
|
||||
* {@link TypeProgramInterface} object.
|
||||
*/
|
||||
public class TypeProgramInterfaceParser {
|
||||
|
||||
|
@ -44,30 +43,29 @@ public class TypeProgramInterfaceParser {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Parses information to determine the version of {@link AbstractTypeProgramInterface} to
|
||||
* create.
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link AbstractTypeProgramInterface}.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return the appropriate {@link AbstractTypeProgramInterface} or null if the stream does
|
||||
* not have enough information to be parsed.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws PdbException Upon error in processing components.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Parses information to determine the version of {@link TypeProgramInterface} to
|
||||
* create
|
||||
* @param pdb {@link AbstractPdb} that owns this {@link TypeProgramInterface}
|
||||
* @return the appropriate {@link TypeProgramInterface} or null if the stream does
|
||||
* not have enough information to be parsed
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public AbstractTypeProgramInterface parse(AbstractPdb pdb, TaskMonitor monitor)
|
||||
public TypeProgramInterface parse(AbstractPdb pdb)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
AbstractTypeProgramInterface typeProgramInterface;
|
||||
TypeProgramInterface typeProgramInterface;
|
||||
|
||||
int versionNumberSize = AbstractTypeProgramInterface.getVersionNumberSize();
|
||||
int versionNumberSize = TypeProgramInterface.getVersionNumberSize();
|
||||
int streamNumber = getStreamNumber();
|
||||
PdbByteReader reader =
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, versionNumberSize, monitor);
|
||||
pdb.getReaderForStreamNumber(streamNumber, 0, versionNumberSize);
|
||||
if (reader.getLimit() < versionNumberSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int versionNumber = AbstractTypeProgramInterface.deserializeVersionNumber(reader);
|
||||
int versionNumber = TypeProgramInterface.deserializeVersionNumber(reader);
|
||||
|
||||
// TODO: we do not know where the line should be drawn for each of these
|
||||
// AbstractTypeProgramInterface instantiations. Had a TI50_ID that was not an 800
|
||||
|
@ -102,8 +100,8 @@ public class TypeProgramInterfaceParser {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the standard stream number that contains the serialized Type Program Interface.
|
||||
* @return The standard stream number that contains the Type Program Interface.
|
||||
* Returns the standard stream number that contains the serialized Type Program Interface
|
||||
* @return the standard stream number that contains the Type Program Interface
|
||||
*/
|
||||
protected int getStreamNumber() {
|
||||
return TYPE_PROGRAM_INTERFACE_STREAM_NUMBER;
|
||||
|
@ -111,8 +109,8 @@ public class TypeProgramInterfaceParser {
|
|||
|
||||
/**
|
||||
* Returns the appropriate {@link RecordCategory} needed while processing
|
||||
* the Type Program Interface} (vs. Item Program Interface).
|
||||
* @return {@link RecordCategory#TYPE}.
|
||||
* the Type Program Interface} (vs. Item Program Interface)
|
||||
* @return {@link RecordCategory#TYPE}
|
||||
*/
|
||||
protected RecordCategory getCategory() {
|
||||
return RecordCategory.TYPE;
|
||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -98,11 +99,11 @@ import ghidra.util.task.TaskMonitor;
|
|||
* <P>
|
||||
* @see MsfFileReader
|
||||
* @see MsfStream
|
||||
* @see AbstractMsfDirectoryStream
|
||||
* @see AbstractMsfFreePageMap
|
||||
* @see AbstractMsfStreamTable
|
||||
* @see MsfDirectoryStream
|
||||
* @see MsfFreePageMap
|
||||
* @see MsfStreamTable
|
||||
*/
|
||||
public abstract class AbstractMsf implements AutoCloseable {
|
||||
public abstract class Msf implements AutoCloseable {
|
||||
|
||||
private static final int HEADER_PAGE_NUMBER = 0;
|
||||
private static final int DIRECTORY_STREAM_NUMBER = 0;
|
||||
|
@ -113,9 +114,9 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
protected String filename;
|
||||
protected MsfFileReader fileReader;
|
||||
|
||||
protected AbstractMsfFreePageMap freePageMap;
|
||||
protected AbstractMsfDirectoryStream directoryStream;
|
||||
protected AbstractMsfStreamTable streamTable;
|
||||
protected MsfFreePageMap freePageMap;
|
||||
protected MsfDirectoryStream directoryStream;
|
||||
protected MsfStreamTable streamTable;
|
||||
|
||||
protected int pageSize;
|
||||
protected int log2PageSize;
|
||||
|
@ -125,23 +126,30 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
protected int currentFreePageMapFirstPageNumber;
|
||||
protected int numPages = 1; // Set to 1 to allow initial read
|
||||
|
||||
protected TaskMonitor monitor;
|
||||
protected PdbReaderOptions pdbOptions;
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor for this class.
|
||||
* @param file The {@link RandomAccessFile} to process for this class.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration.
|
||||
* Constructor
|
||||
* @param file the {@link RandomAccessFile} to process for this class
|
||||
* @param filename name of {@code #file}
|
||||
* @param monitor the TaskMonitor
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration
|
||||
*/
|
||||
public AbstractMsf(RandomAccessFile file, PdbReaderOptions pdbOptions)
|
||||
public Msf(RandomAccessFile file, String filename, TaskMonitor monitor,
|
||||
PdbReaderOptions pdbOptions)
|
||||
throws IOException, PdbException {
|
||||
Objects.requireNonNull(file, "file may not be null");
|
||||
this.filename = Objects.requireNonNull(filename, "filename may not be null");
|
||||
this.monitor = TaskMonitor.dummyIfNull(monitor);
|
||||
this.pdbOptions = Objects.requireNonNull(pdbOptions, "PdbOptions may not be null");
|
||||
// Do initial configuration with largest possible page size. ConfigureParameters will
|
||||
// be called again later with the proper pageSize set.
|
||||
this.pdbOptions = pdbOptions;
|
||||
pageSize = 0x1000;
|
||||
configureParameters();
|
||||
// Create components.
|
||||
|
@ -150,34 +158,58 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the page size employed by this {@link AbstractMsf}.
|
||||
* @return Page size.
|
||||
* Returns the filename
|
||||
* @return the filename
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TaskMonitor
|
||||
* @return the monitor
|
||||
*/
|
||||
public TaskMonitor getMonitor() {
|
||||
return monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this monitor has been canceled
|
||||
* @throws CancelledException if monitor has been cancelled
|
||||
*/
|
||||
public void checkCanceled() throws CancelledException {
|
||||
monitor.checkCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page size employed by this {@link Msf}
|
||||
* @return page size
|
||||
*/
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of streams found in this {@link AbstractMsf}.
|
||||
* @return Number of streams.
|
||||
* Returns the number of streams found in this {@link Msf}
|
||||
* @return number of streams
|
||||
*/
|
||||
public int getNumStreams() {
|
||||
return streamTable.getNumStreams();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MsfStream} specified by {@link AbstractMsf}.
|
||||
* @param streamNumber The number of the Stream to return. Must be less than the number
|
||||
* of streams returned by {@link #getNumStreams()}.
|
||||
* @return {@link MsfStream} or {@code null} if no stream for the streamNumber.
|
||||
* Returns the {@link MsfStream} specified by {@link Msf}
|
||||
* @param streamNumber the number of the Stream to return. Must be less than the number
|
||||
* of streams returned by {@link #getNumStreams()}
|
||||
* @return {@link MsfStream} or {@code null} if no stream for the streamNumber
|
||||
*/
|
||||
public MsfStream getStream(int streamNumber) {
|
||||
return streamTable.getStream(streamNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes resources used by this {@link AbstractMsf}.
|
||||
* @throws IOException Under circumstances found when closing a {@link RandomAccessFile}.
|
||||
* Closes resources used by this {@link Msf}
|
||||
* @throws IOException under circumstances found when closing a {@link RandomAccessFile}
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
@ -191,10 +223,10 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Returns the value of the floor (greatest integer less than or equal to) of the result
|
||||
* upon dividing the dividend by a divisor which is the power-of-two of the log2Divisor.
|
||||
* @param dividend The dividend to the operator
|
||||
* @param log2Divisor The log2 of the intended divisor value.
|
||||
* @return The floor of the division result.
|
||||
* upon dividing the dividend by a divisor which is the power-of-two of the log2Divisor
|
||||
* @param dividend the dividend to the operator
|
||||
* @param log2Divisor the log2 of the intended divisor value
|
||||
* @return the floor of the division result
|
||||
*/
|
||||
static final int floorDivisionWithLog2Divisor(int dividend, int log2Divisor) {
|
||||
return (dividend + (1 << log2Divisor) - 1) >> log2Divisor;
|
||||
|
@ -204,46 +236,45 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Method that returns the identification byte[] required by this format.
|
||||
* @return The minimum required number.
|
||||
* Method that returns the identification byte[] required by this format
|
||||
* @return the minimum required number
|
||||
*/
|
||||
protected abstract byte[] getIdentification();
|
||||
|
||||
/**
|
||||
* Returns the offset (in bytes) of the PageSize within the header.
|
||||
* @return The offset of the PageSize within the header.
|
||||
* Returns the offset (in bytes) of the PageSize within the header
|
||||
* @return the offset of the PageSize within the header
|
||||
*/
|
||||
protected abstract int getPageSizeOffset();
|
||||
|
||||
/**
|
||||
* Deserializes the Free Page Map page number from the {@link PdbByteReader}.
|
||||
* @param reader {@link PdbByteReader} from which to read.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the Free Page Map page number from the {@link PdbByteReader}
|
||||
* @param reader {@link PdbByteReader} from which to read
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected abstract void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Deserializes the value of the number of pages in the MSF.
|
||||
* @param reader {@link PdbByteReader} from which to read.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Deserializes the value of the number of pages in the MSF
|
||||
* @param reader {@link PdbByteReader} from which to read
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected abstract void parseCurrentNumPages(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Method to create the following components: StreamTable, FreePageMap, and DirectoryStream.
|
||||
* FreePageMap.
|
||||
*/
|
||||
abstract void create();
|
||||
|
||||
/**
|
||||
* Method to set parameters for the file based on version and page size.
|
||||
* @throws PdbException Upon unknown value for configuration.
|
||||
* Method to set parameters for the file based on version and page size
|
||||
* @throws PdbException upon unknown value for configuration
|
||||
*/
|
||||
abstract void configureParameters() throws PdbException;
|
||||
|
||||
/**
|
||||
* Method to get the size of the page number (in bytes) when serialized to disc.
|
||||
* @return The page size (in bytes).
|
||||
* Method to get the size of the page number (in bytes) when serialized to disc
|
||||
* @return the page size (in bytes)
|
||||
*/
|
||||
abstract protected int getPageNumberSize();
|
||||
|
||||
|
@ -251,8 +282,8 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
// Class Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns Log2 value of the page size employed by this MSF.
|
||||
* @return The Log2 value of the page size employed by this MSF.
|
||||
* Returns Log2 value of the page size employed by this MSF
|
||||
* @return the Log2 value of the page size employed by this MSF
|
||||
*/
|
||||
protected int getLog2PageSize() {
|
||||
return log2PageSize;
|
||||
|
@ -260,33 +291,33 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
|
||||
/**
|
||||
* Returns the the mask used for masking off the upper bits of a value use to get the
|
||||
* mod-page-size of the value (pageSizes must be power of two for this to work).
|
||||
* @return The mask.
|
||||
* mod-page-size of the value (pageSizes must be power of two for this to work)
|
||||
* @return the mask
|
||||
*/
|
||||
protected int getPageSizeModMask() {
|
||||
return pageSizeModMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of pages found in sequence that compose the {@link AbstractMsfFreePageMap}
|
||||
* (for this {@link AbstractMsf}) when on disk.
|
||||
* @return The number of sequential pages in the {@link AbstractMsfFreePageMap}.
|
||||
* Returns the number of pages found in sequence that compose the {@link MsfFreePageMap}
|
||||
* (for this {@link Msf}) when on disk
|
||||
* @return the number of sequential pages in the {@link MsfFreePageMap}
|
||||
*/
|
||||
protected int getNumSequentialFreePageMapPages() {
|
||||
return freePageMapNumSequentialPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page number containing the header of this MSF file.
|
||||
* @return The header page number.
|
||||
* Returns the page number containing the header of this MSF file
|
||||
* @return the header page number
|
||||
*/
|
||||
protected int getHeaderPageNumber() {
|
||||
return HEADER_PAGE_NUMBER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream number containing the directory of this MSF file.
|
||||
* @return The directory stream number.
|
||||
* Returns the stream number containing the directory of this MSF file
|
||||
* @return the directory stream number
|
||||
*/
|
||||
protected int getDirectoryStreamNumber() {
|
||||
return DIRECTORY_STREAM_NUMBER;
|
||||
|
@ -296,16 +327,16 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the number of pages contained in this MSF file.
|
||||
* @return The number of pages in this MSF.
|
||||
* Returns the number of pages contained in this MSF file
|
||||
* @return the number of pages in this MSF
|
||||
*/
|
||||
protected int getNumPages() {
|
||||
return numPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first page number of the current Free Page Map.
|
||||
* @return The first page number of the current Free Page Map.
|
||||
* Returns the first page number of the current Free Page Map
|
||||
* @return the first page number of the current Free Page Map
|
||||
*/
|
||||
protected int getCurrentFreePageMapFirstPageNumber() {
|
||||
return currentFreePageMapFirstPageNumber;
|
||||
|
@ -314,14 +345,13 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
/**
|
||||
* Performs required initialization of this class, needed before trying to read any
|
||||
* Streams. Initialization includes deserializing the remainder of the header as well
|
||||
* as stream directory information.
|
||||
* @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.
|
||||
* @throws PdbException Upon unknown value for configuration.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* as stream directory information
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon unknown value for configuration
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void deserialize(TaskMonitor monitor)
|
||||
protected void deserialize()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
byte[] bytes = new byte[getPageSize()];
|
||||
fileReader.read(getHeaderPageNumber(), 0, getPageSize(), bytes, 0);
|
||||
|
@ -333,13 +363,13 @@ public abstract class AbstractMsf implements AutoCloseable {
|
|||
parseCurrentNumPages(reader);
|
||||
configureParameters();
|
||||
|
||||
directoryStream.deserializeStreamInfo(reader, monitor);
|
||||
directoryStream.deserializeStreamInfo(reader);
|
||||
|
||||
// Do not need FreePageMap for just reading files.
|
||||
freePageMap.deserialize(monitor);
|
||||
freePageMap.deserialize();
|
||||
// For debug: freePageMap.dump();
|
||||
|
||||
streamTable.deserialize(directoryStream, monitor);
|
||||
streamTable.deserialize(directoryStream);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,11 +20,12 @@ import java.io.RandomAccessFile;
|
|||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsf} for Microsoft v2.00 MSF.
|
||||
* This class is the version of {@link Msf} for Microsoft v2.00 MSF.
|
||||
*/
|
||||
public class Msf200 extends AbstractMsf {
|
||||
public class Msf200 extends Msf {
|
||||
|
||||
private static final int PAGE_NUMBER_SIZE = 2;
|
||||
private static final byte[] IDENTIFICATION =
|
||||
|
@ -39,25 +40,28 @@ public class Msf200 extends AbstractMsf {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param file The {@link RandomAccessFile} to process as a {@link Msf200}.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration.
|
||||
* Constructor
|
||||
* @param file the {@link RandomAccessFile} to process as a {@link Msf200}
|
||||
* @param filename name of {@code #file}
|
||||
* @param monitor the TaskMonitor
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration
|
||||
*/
|
||||
public Msf200(RandomAccessFile file, PdbReaderOptions pdbOptions)
|
||||
public Msf200(RandomAccessFile file, String filename, TaskMonitor monitor,
|
||||
PdbReaderOptions pdbOptions)
|
||||
throws IOException, PdbException {
|
||||
super(file, pdbOptions);
|
||||
super(file, filename, monitor, pdbOptions);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Static method used to detect the header that belongs to this class.
|
||||
* @param file The {@link RandomAccessFile} to process as a {@link Msf200}.
|
||||
* @return True if the header for this class is positively identified.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* Static method used to detect the header that belongs to this class
|
||||
* @param file the {@link RandomAccessFile} to process as a {@link Msf200}
|
||||
* @return {@code true} if the header for this class is positively identified
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
*/
|
||||
static boolean detected(RandomAccessFile file) throws IOException {
|
||||
byte[] bytes = new byte[IDENTIFICATION.length];
|
||||
|
|
|
@ -20,11 +20,12 @@ import java.io.RandomAccessFile;
|
|||
import java.util.Arrays;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsf} for Microsoft v7.00 MSF.
|
||||
* This class is the version of {@link Msf} for Microsoft v7.00 MSF.
|
||||
*/
|
||||
public class Msf700 extends AbstractMsf {
|
||||
public class Msf700 extends Msf {
|
||||
|
||||
private static final int PAGE_NUMBER_SIZE = 4;
|
||||
private static final byte[] IDENTIFICATION = "Microsoft C/C++ MSF 7.00\r\n\u001aDS".getBytes();
|
||||
|
@ -38,15 +39,18 @@ public class Msf700 extends AbstractMsf {
|
|||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param file The {@link RandomAccessFile} to process as a {@link Msf700}.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration.
|
||||
* Constructor
|
||||
* @param file the {@link RandomAccessFile} to process as a {@link Msf700}
|
||||
* @param filename name of {@code #file}
|
||||
* @param monitor the TaskMonitor
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration
|
||||
*/
|
||||
public Msf700(RandomAccessFile file, PdbReaderOptions pdbOptions)
|
||||
public Msf700(RandomAccessFile file, String filename, TaskMonitor monitor,
|
||||
PdbReaderOptions pdbOptions)
|
||||
throws IOException, PdbException {
|
||||
super(file, pdbOptions);
|
||||
super(file, filename, monitor, pdbOptions);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
|
@ -98,10 +102,10 @@ public class Msf700 extends AbstractMsf {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Static method used to detect the header that belongs to this class.
|
||||
* @param file The RandomAccessFile to process as a {@link Msf700}.
|
||||
* @return True if the header for this class is positively identified.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* Static method used to detect the header that belongs to this class
|
||||
* @param file the RandomAccessFile to process as a {@link Msf700}
|
||||
* @return {@code true} if the header for this class is positively identified
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
*/
|
||||
static boolean detected(RandomAccessFile file) throws IOException {
|
||||
byte[] bytes = new byte[IDENTIFICATION.length];
|
||||
|
|
|
@ -20,26 +20,26 @@ package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
|||
* in the older style MSF format, it was the same as a user (@link MsfStream}. Newer versions of
|
||||
* MSF needed a higher capacity stream
|
||||
* Class extends {@link MsfStream} and represents a more complex Stream used as the Directory Stream
|
||||
* for the newer {@link AbstractMsf} (and PDB) format. In the older format, a regular
|
||||
* for the newer {@link Msf} (and PDB) format. In the older format, a regular
|
||||
* Stream is used as the directory Stream.
|
||||
* <P>
|
||||
* Note: This extended Stream is not used as a user Stream--just as a higher-capacity directory
|
||||
* Stream.
|
||||
* <P>
|
||||
* The format of how this {@link AbstractMsfDirectoryStream} is persisted to disk is described in
|
||||
* the main {@link AbstractMsf} documentation.
|
||||
* The format of how this {@link MsfDirectoryStream} is persisted to disk is described in
|
||||
* the main {@link Msf} documentation.
|
||||
*/
|
||||
abstract class AbstractMsfDirectoryStream extends MsfStream {
|
||||
abstract class MsfDirectoryStream extends MsfStream {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor. Sets the byte length of the Stream to -1. This method is used when the
|
||||
* Stream knows/reads its length.
|
||||
* @param msf The {@link AbstractMsf} to which the Stream belongs.
|
||||
* Stream knows/reads its length
|
||||
* @param msf the {@link Msf} to which the Stream belongs
|
||||
*/
|
||||
AbstractMsfDirectoryStream(AbstractMsf msf) {
|
||||
MsfDirectoryStream(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
|
@ -16,21 +16,21 @@
|
|||
package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
||||
|
||||
/**
|
||||
* This is the v200 of {@link AbstractMsfDirectoryStream}. It is essentially no different than
|
||||
* This is the v200 of {@link MsfDirectoryStream}. It is essentially no different than
|
||||
* an {@link MsfStream}.
|
||||
* @see AbstractMsfDirectoryStream
|
||||
* @see MsfDirectoryStream
|
||||
*/
|
||||
class MsfDirectoryStream200 extends AbstractMsfDirectoryStream {
|
||||
class MsfDirectoryStream200 extends MsfDirectoryStream {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor. Sets the byte length of the Stream to -1. This method is used when the
|
||||
* Stream knows/reads its length.
|
||||
* @param msf The {@link AbstractMsf} to which the Stream belongs.
|
||||
* Stream knows/reads its length
|
||||
* @param msf the {@link Msf} to which the Stream belongs
|
||||
*/
|
||||
MsfDirectoryStream200(AbstractMsf msf) {
|
||||
MsfDirectoryStream200(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,23 @@ import java.io.IOException;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This is the v700 of {@link AbstractMsfDirectoryStream}. It is essentially no different than
|
||||
* This is the v700 of {@link MsfDirectoryStream}. It is essentially no different than
|
||||
* an {@link MsfStream}.
|
||||
* @see AbstractMsfDirectoryStream
|
||||
* @see MsfDirectoryStream
|
||||
*/
|
||||
class MsfDirectoryStream700 extends AbstractMsfDirectoryStream {
|
||||
class MsfDirectoryStream700 extends MsfDirectoryStream {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor. Sets the byte length of the Stream to -1. This method is used when the
|
||||
* Stream knows/reads its length.
|
||||
* @param msf The {@link AbstractMsf} to which the Stream belongs.
|
||||
* Stream knows/reads its length
|
||||
* @param msf the {@link Msf} to which the Stream belongs
|
||||
*/
|
||||
MsfDirectoryStream700(AbstractMsf msf) {
|
||||
MsfDirectoryStream700(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
@ -45,20 +44,19 @@ class MsfDirectoryStream700 extends AbstractMsfDirectoryStream {
|
|||
* Deserializes Stream information from the bytes parameter starting at the index offset
|
||||
* and uses it to provide necessary information for the Stream to be usable.
|
||||
* The information from the deserialization of the byte parameter then points to additional
|
||||
* {@link AbstractMsf} pages that need to be read as a subStream and deserialized to create
|
||||
* {@link Msf} pages that need to be read as a subStream and deserialized to create
|
||||
* the {@link MsfDirectoryStream700}.
|
||||
* <P>
|
||||
* Generally, deserialization is part of the step of loading the Stream information from
|
||||
* persistent storage (disk).
|
||||
* @param reader {@link PdbByteReader} from which to parse the information.
|
||||
* @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.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* @param reader {@link PdbByteReader} from which to parse the information
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
@Override
|
||||
void deserializeStreamInfo(PdbByteReader reader, TaskMonitor monitor)
|
||||
void deserializeStreamInfo(PdbByteReader reader)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
|
||||
// Parse the length of the overall (larger) stream.
|
||||
|
@ -66,18 +64,18 @@ class MsfDirectoryStream700 extends AbstractMsfDirectoryStream {
|
|||
// Calculate the length of the subStream which contains all of the page numbers necessary
|
||||
// for the overall (larger) stream and create a subStream with this calculated length.
|
||||
int subStreamLength =
|
||||
AbstractMsf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize()) *
|
||||
Msf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize()) *
|
||||
msf.getPageNumberSize();
|
||||
|
||||
MsfStream subStream = new MsfStream(msf, subStreamLength);
|
||||
// Parse the page numbers of the subStream.
|
||||
subStream.deserializePageNumbers(reader, monitor);
|
||||
subStream.deserializePageNumbers(reader);
|
||||
// Now read the whole subStream, creating a new byte array.
|
||||
byte[] bytes = subStream.read(0, subStreamLength, monitor);
|
||||
byte[] bytes = subStream.read(0, subStreamLength);
|
||||
PdbByteReader pageNumberReader = new PdbByteReader(bytes);
|
||||
// Next parse the page numbers for the overall (larger) stream from this new byte array
|
||||
// that was read from the subStream.
|
||||
deserializePageNumbers(pageNumberReader, monitor);
|
||||
deserializePageNumbers(pageNumberReader);
|
||||
// The overall (larger) stream has now been set up with the overall stream length
|
||||
// and its page numbers parsed.
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.io.RandomAccessFile;
|
|||
|
||||
/**
|
||||
* This class is responsible for reading pages from a {@link RandomAccessFile} for the
|
||||
* {@link AbstractMsf} class and its underlying classes.
|
||||
* {@link Msf} class and its underlying classes.
|
||||
*/
|
||||
class MsfFileReader implements AutoCloseable {
|
||||
|
||||
|
@ -28,14 +28,14 @@ class MsfFileReader implements AutoCloseable {
|
|||
// Internals
|
||||
//==============================================================================================
|
||||
private RandomAccessFile file;
|
||||
private AbstractMsf msf;
|
||||
private Msf msf;
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Closes this class, including its underlying file resources.
|
||||
* @throws IOException Under circumstances found when closing a {@link RandomAccessFile}.
|
||||
* Closes this class, including its underlying file resources
|
||||
* @throws IOException under circumstances found when closing a {@link RandomAccessFile}
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
@ -48,35 +48,35 @@ class MsfFileReader implements AutoCloseable {
|
|||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The {@link AbstractMsf} for which this class is to be associated.
|
||||
* @param file {@link RandomAccessFile} underlying this class.
|
||||
* Constructor
|
||||
* @param msf the {@link Msf} for which this class is to be associated
|
||||
* @param file {@link RandomAccessFile} underlying this class
|
||||
*/
|
||||
MsfFileReader(AbstractMsf msf, RandomAccessFile file) {
|
||||
MsfFileReader(Msf msf, RandomAccessFile file) {
|
||||
this.msf = msf;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single page of bytes from the {@link AbstractMsf} and writes it into the bytes array.
|
||||
* @param page The page number to read from the file.
|
||||
* @param bytes The byte[] into which the data is to be written.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* Reads a single page of bytes from the {@link Msf} and writes it into the bytes array
|
||||
* @param page the page number to read from the file
|
||||
* @param bytes the byte[] into which the data is to be written
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
*/
|
||||
void readPage(int page, byte[] bytes) throws IOException {
|
||||
read(page, 0, msf.getPageSize(), bytes, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads bytes from the {@link AbstractMsf} into a byte[].
|
||||
* @param page The page number within which to start the read.
|
||||
* @param offset The byte offset within the page to start the read.
|
||||
* @param numToRead The total number of bytes to read.
|
||||
* @param bytes The byte[] into which the data is to be written.
|
||||
* @param bytesOffset The starting offset within the bytes array in which to start writing.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* Reads bytes from the {@link Msf} into a byte[]
|
||||
* @param page the page number within which to start the read
|
||||
* @param offset the byte offset within the page to start the read
|
||||
* @param numToRead the total number of bytes to read
|
||||
* @param bytes the byte[] into which the data is to be written
|
||||
* @param bytesOffset the starting offset within the bytes array in which to start writing
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
*/
|
||||
void read(int page, int offset, int numToRead, byte[] bytes, int bytesOffset)
|
||||
throws IOException {
|
||||
|
@ -95,7 +95,7 @@ class MsfFileReader implements AutoCloseable {
|
|||
|
||||
// Fail if file does not contain enough pages for the read--boundary case that assumes
|
||||
// everything beyond the offset in the file belongs to this read.
|
||||
if (AbstractMsf.floorDivisionWithLog2Divisor(offset + numToRead,
|
||||
if (Msf.floorDivisionWithLog2Divisor(offset + numToRead,
|
||||
msf.getLog2PageSize()) > msf.getNumPages()) {
|
||||
throw new IOException("Invalid MSF configuration");
|
||||
}
|
||||
|
|
|
@ -20,11 +20,10 @@ import java.util.*;
|
|||
|
||||
import ghidra.util.LittleEndianDataConverter;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the Free Page Map for the Multi-Stream Format File (see Microsoft API). The
|
||||
* Free Page Map is a bit-encoding of whether a page within the {@link AbstractMsf} is
|
||||
* Free Page Map is a bit-encoding of whether a page within the {@link Msf} is
|
||||
* currently used--for purposes of reusing available pages.
|
||||
* <P>
|
||||
* This class was crafted to take the place of the formal Free Page Map in a complete
|
||||
|
@ -35,7 +34,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
* ENGINEERING PATH: Use java.util.BitSet for storage after processing. Could probably eliminate
|
||||
* the {@code List<Integer> map} storage.
|
||||
*/
|
||||
abstract class AbstractMsfFreePageMap {
|
||||
abstract class MsfFreePageMap {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
|
@ -44,22 +43,22 @@ abstract class AbstractMsfFreePageMap {
|
|||
private List<Integer> map = new ArrayList<>();
|
||||
protected static final int MAP_FIELD_SIZE = Integer.BYTES;
|
||||
|
||||
protected AbstractMsf msf;
|
||||
protected Msf msf;
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The {@link AbstractMsf} to which this class belongs.
|
||||
* Constructor
|
||||
* @param msf the {@link Msf} to which this class belongs
|
||||
*/
|
||||
AbstractMsfFreePageMap(AbstractMsf msf) {
|
||||
MsfFreePageMap(Msf msf) {
|
||||
this.msf = msf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug method to dump some of the internals of this class.
|
||||
* @return Data dumped in a pretty format.
|
||||
* Debug method to dump some of the internals of this class
|
||||
* @return data dumped in a pretty format
|
||||
*/
|
||||
String dump() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -80,19 +79,18 @@ abstract class AbstractMsfFreePageMap {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Method used to deserialize this class from disk.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Method used to deserialize this class from disc
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
abstract void deserialize(TaskMonitor monitor) throws IOException, CancelledException;
|
||||
abstract void deserialize() throws IOException, CancelledException;
|
||||
|
||||
/**
|
||||
* Method indicating whether the Free Page Map is a "Big" Free Page Map. Currently, we have
|
||||
* at least two types extending this class. One is "Big" (the newer v7.00) and the other is
|
||||
* not. The {@link #dump()} method makes use of this method.
|
||||
* @return true if it is a "Big" version of this class.
|
||||
* not. The {@link #dump()} method makes use of this method
|
||||
* @return {@code true} if it is a "Big" version of this class
|
||||
*/
|
||||
abstract boolean isBig();
|
||||
|
||||
|
@ -100,16 +98,15 @@ abstract class AbstractMsfFreePageMap {
|
|||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Internal method for adding a records to the map from the {@code byte[]} argument.
|
||||
* @param bytes The {@code byte[]} containing the data.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Internal method for adding a records to the map from the {@code byte[]} argument
|
||||
* @param bytes the {@code byte[]} containing the data
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected void addMap(byte[] bytes, TaskMonitor monitor) throws CancelledException {
|
||||
protected void addMap(byte[] bytes) throws CancelledException {
|
||||
// TODO: If we implement FreePageMap further, then consider passing in a PdbByteReader
|
||||
// and using the reader to parse the appropriate Integral types.
|
||||
for (int index = 0; index < bytes.length - MAP_FIELD_SIZE; index += MAP_FIELD_SIZE) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
byte[] selectedBytes = Arrays.copyOfRange(bytes, index, index + MAP_FIELD_SIZE);
|
||||
map.add(LittleEndianDataConverter.INSTANCE.getInt(selectedBytes));
|
||||
}
|
|
@ -18,21 +18,20 @@ package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
|||
import java.io.IOException;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsfFreePageMap} for Microsoft v2.00 Free Page Map.
|
||||
* This class is the version of {@link MsfFreePageMap} for Microsoft v2.00 Free Page Map.
|
||||
*/
|
||||
class MsfFreePageMap200 extends AbstractMsfFreePageMap {
|
||||
class MsfFreePageMap200 extends MsfFreePageMap {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The {@link AbstractMsf} to which this class belongs.
|
||||
* Constructor
|
||||
* @param msf the {@link Msf} to which this class belongs
|
||||
*/
|
||||
MsfFreePageMap200(AbstractMsf msf) {
|
||||
MsfFreePageMap200(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
@ -42,12 +41,12 @@ class MsfFreePageMap200 extends AbstractMsfFreePageMap {
|
|||
}
|
||||
|
||||
@Override
|
||||
void deserialize(TaskMonitor monitor) throws IOException, CancelledException {
|
||||
void deserialize() throws IOException, CancelledException {
|
||||
int size = msf.getNumSequentialFreePageMapPages() * msf.getPageSize();
|
||||
byte[] bytes = new byte[size];
|
||||
MsfFileReader fileReader = msf.fileReader;
|
||||
fileReader.read(msf.getCurrentFreePageMapFirstPageNumber(), 0, size, bytes, 0);
|
||||
addMap(bytes, monitor);
|
||||
addMap(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,21 +18,20 @@ package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
|||
import java.io.IOException;
|
||||
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsfFreePageMap} for Microsoft v7.00 Free Page Map.
|
||||
* This class is the version of {@link MsfFreePageMap} for Microsoft v7.00 Free Page Map.
|
||||
*/
|
||||
class MsfFreePageMap700 extends AbstractMsfFreePageMap {
|
||||
class MsfFreePageMap700 extends MsfFreePageMap {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The {@link AbstractMsf} to which this class belongs.
|
||||
* Constructor
|
||||
* @param msf the {@link Msf} to which this class belongs
|
||||
*/
|
||||
MsfFreePageMap700(AbstractMsf msf) {
|
||||
MsfFreePageMap700(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
@ -42,11 +41,11 @@ class MsfFreePageMap700 extends AbstractMsfFreePageMap {
|
|||
}
|
||||
|
||||
@Override
|
||||
void deserialize(TaskMonitor monitor) throws IOException, CancelledException {
|
||||
void deserialize() throws IOException, CancelledException {
|
||||
// Calculate the number of pages that the FreePageMap occupies on disk.
|
||||
int log2BitsPerPage = msf.getLog2PageSize() + 3; // 3 = log2(bitsperbyte)
|
||||
long freePageMapNumPages =
|
||||
AbstractMsf.floorDivisionWithLog2Divisor(msf.getNumPages(), log2BitsPerPage);
|
||||
Msf.floorDivisionWithLog2Divisor(msf.getNumPages(), log2BitsPerPage);
|
||||
|
||||
// Get the First page number of the FreePageMap on disk.
|
||||
int nextPageNumber = msf.getCurrentFreePageMapFirstPageNumber();
|
||||
|
@ -55,10 +54,10 @@ class MsfFreePageMap700 extends AbstractMsfFreePageMap {
|
|||
MsfFileReader fileReader = msf.fileReader;
|
||||
int pageSize = msf.getPageSize();
|
||||
while (freePageMapNumPages > 0) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
byte[] bytes = new byte[pageSize];
|
||||
fileReader.read(nextPageNumber, 0, pageSize, bytes, 0);
|
||||
addMap(bytes, monitor);
|
||||
addMap(bytes);
|
||||
freePageMapNumPages--;
|
||||
// This is correct. Each page of the FreePageMap700 is located at pageSize number
|
||||
// of pages away from the last page. So if the first page of the FreePageMap700
|
||||
|
|
|
@ -25,35 +25,35 @@ import ghidra.util.exception.CancelledException;
|
|||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Parser for detecting the appropriate {@link AbstractMsf} format for the filename given.
|
||||
* It then creates and returns the appropriate {@link AbstractMsf} object.
|
||||
* Parser for detecting the appropriate {@link Msf} format for the filename given.
|
||||
* It then creates and returns the appropriate {@link Msf} object.
|
||||
*/
|
||||
public class MsfParser {
|
||||
|
||||
/**
|
||||
* Detects, creates, and returns the appropriate {@link AbstractMsf} object found for
|
||||
* the filename given.
|
||||
* @param filename Filename of the file to process.
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return Derived {@link AbstractMsf} object.
|
||||
* @throws IOException For file I/O reasons
|
||||
* @throws PdbException If an appropriate object cannot be created.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Detects, creates, and returns the appropriate {@link Msf} object found for
|
||||
* the filename given
|
||||
* @param filename name of the file to process
|
||||
* @param pdbOptions {@link PdbReaderOptions} used for processing the PDB
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation
|
||||
* @return derived {@link Msf} object
|
||||
* @throws IOException for file I/O reasons
|
||||
* @throws PdbException if an appropriate object cannot be created
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public static AbstractMsf parse(String filename, PdbReaderOptions pdbOptions,
|
||||
public static Msf parse(String filename, PdbReaderOptions pdbOptions,
|
||||
TaskMonitor monitor) throws IOException, PdbException, CancelledException {
|
||||
Objects.requireNonNull(filename, "filename cannot be null");
|
||||
Objects.requireNonNull(pdbOptions, "pdbOptions cannot be null");
|
||||
Objects.requireNonNull(monitor, "monitor cannot be null");
|
||||
|
||||
AbstractMsf msf;
|
||||
Msf msf;
|
||||
RandomAccessFile file = new RandomAccessFile(filename, "r");
|
||||
if (Msf200.detected(file)) {
|
||||
msf = new Msf200(file, pdbOptions);
|
||||
msf = new Msf200(file, filename, monitor, pdbOptions);
|
||||
}
|
||||
else if (Msf700.detected(file)) {
|
||||
msf = new Msf700(file, pdbOptions);
|
||||
msf = new Msf700(file, filename, monitor, pdbOptions);
|
||||
}
|
||||
else {
|
||||
// Must close the file here. In cases where MSF is created, the MSF takes
|
||||
|
@ -61,7 +61,7 @@ public class MsfParser {
|
|||
file.close();
|
||||
throw new PdbException("MSF format not detected");
|
||||
}
|
||||
msf.deserialize(monitor);
|
||||
msf.deserialize();
|
||||
return msf;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,17 +23,16 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Class representing a Stream within an {@link AbstractMsf}--see its write-up.
|
||||
* Class representing a Stream within an {@link Msf}--see its write-up.
|
||||
* <P>
|
||||
* The stream can only be read, as it is part of a reader capability, not a read/write/modify
|
||||
* capability.
|
||||
* <P>
|
||||
* The Stream can get initialized through a couple of mechanisms, but the essential information
|
||||
* is the stream length, the map of stream page numbers to file page numbers, and the
|
||||
* referenced {@link AbstractMsf} to which it belongs, which contains most other
|
||||
* referenced {@link Msf} to which it belongs, which contains most other
|
||||
* information that it needs.
|
||||
*/
|
||||
public class MsfStream {
|
||||
|
@ -48,14 +47,14 @@ public class MsfStream {
|
|||
//==============================================================================================
|
||||
protected int streamLength;
|
||||
protected List<Integer> pageList = new ArrayList<>();
|
||||
protected AbstractMsf msf;
|
||||
protected Msf msf;
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the length of the Stream.
|
||||
* @return Byte-length of Stream.
|
||||
* Returns the length of the Stream
|
||||
* @return byte-length of Stream
|
||||
*/
|
||||
public int getLength() {
|
||||
return streamLength;
|
||||
|
@ -64,40 +63,38 @@ public class MsfStream {
|
|||
/**
|
||||
* Reads numToRead bytes from the stream starting at streamOffset within the stream.
|
||||
* Returns the byte array containing the read information. If not all bytes are available
|
||||
* to be read, an IOException will be thrown.
|
||||
* @param streamOffset Location within the stream from where to start reading bytes.
|
||||
* @param numToRead Number of bytes to read from the stream.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @return byte[] containing the bytes read.
|
||||
* @throws IOException On file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* to be read, an IOException will be thrown
|
||||
* @param streamOffset location within the stream from where to start reading bytes
|
||||
* @param numToRead number of bytes to read from the stream
|
||||
* @return byte[] containing the bytes read
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public byte[] read(int streamOffset, int numToRead, TaskMonitor monitor)
|
||||
public byte[] read(int streamOffset, int numToRead)
|
||||
throws IOException, CancelledException {
|
||||
if (numToRead <= 0) {
|
||||
return null;
|
||||
}
|
||||
byte[] bytes = new byte[numToRead];
|
||||
read(streamOffset, bytes, 0, numToRead, monitor);
|
||||
read(streamOffset, bytes, 0, numToRead);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads numToRead bytes from the stream starting at streamOffset within the stream.
|
||||
* The bytes are written into the bytes array starting at the bytesOffset location.
|
||||
* If not all bytes are available to be read, an IOException will be thrown.
|
||||
* @param streamOffset Location within the stream from where to start reading bytes.
|
||||
* @param bytes The array into which to write the data.
|
||||
* @param bytesOffset The location within byte array at which to start writing data.
|
||||
* @param numToRead Number of bytes to read from the stream.
|
||||
* @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.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* If not all bytes are available to be read, an IOException will be thrown
|
||||
* @param streamOffset location within the stream from where to start reading bytes
|
||||
* @param bytes the array into which to write the data
|
||||
* @param bytesOffset the location within byte array at which to start writing data
|
||||
* @param numToRead number of bytes to read from the stream
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public void read(int streamOffset, byte[] bytes, int bytesOffset, int numToRead,
|
||||
TaskMonitor monitor) throws IOException, CancelledException {
|
||||
public void read(int streamOffset, byte[] bytes, int bytesOffset, int numToRead)
|
||||
throws IOException, CancelledException {
|
||||
if (streamOffset < 0 || streamOffset > streamLength) {
|
||||
throw new IOException("Offset out of range.");
|
||||
}
|
||||
|
@ -127,13 +124,13 @@ public class MsfStream {
|
|||
// Read remaining pages, including last as possible partial page.
|
||||
// Outer loop iterates over possible non-sequential groups.
|
||||
while (remainingByteCount > 0) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
// Inner loop groups together sequential pages into one big read.
|
||||
int firstSequentialPageNumber = pageList.get(pageNumber);
|
||||
int lastSequentialPageNumber = firstSequentialPageNumber;
|
||||
int numToReadInSequentialPages = 0;
|
||||
do {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
pageNumber++;
|
||||
lastSequentialPageNumber++;
|
||||
int numToReadInPage = Math.min(msf.getPageSize(), remainingByteCount);
|
||||
|
@ -148,9 +145,9 @@ public class MsfStream {
|
|||
}
|
||||
|
||||
/**
|
||||
* Debug method to dump the PDB Directory in a pretty format to String.
|
||||
* @param maxOut Maximum number of bytes to output.
|
||||
* @return {@link String} containing the pretty output.
|
||||
* Debug method to dump the PDB Directory in a pretty format to String
|
||||
* @param maxOut maximum number of bytes to output
|
||||
* @return {@link String} containing the pretty output
|
||||
*/
|
||||
public String dump(int maxOut) {
|
||||
int outputLength = Math.min(getLength(), maxOut);
|
||||
|
@ -164,7 +161,7 @@ public class MsfStream {
|
|||
}
|
||||
byte[] bytes = new byte[outputLength];
|
||||
try {
|
||||
read(0, bytes, 0, outputLength, TaskMonitor.DUMMY);
|
||||
read(0, bytes, 0, outputLength);
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Should not occur. We limited our request to be <= the Stream length.
|
||||
|
@ -188,21 +185,21 @@ public class MsfStream {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Package-protected constructor of a PDB Stream. Sets the byte length of the
|
||||
* Stream to -1. This method is used when the Stream knows/reads its length.
|
||||
* @param msf The {@link AbstractMsf} to which the Stream belongs.
|
||||
* Stream to -1. This method is used when the Stream knows/reads its length
|
||||
* @param msf the {@link Msf} to which the Stream belongs
|
||||
*/
|
||||
MsfStream(AbstractMsf msf) {
|
||||
MsfStream(Msf msf) {
|
||||
streamLength = -1;
|
||||
this.msf = msf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-protected constructor of a PDB Stream. This method is used when the
|
||||
* stream length comes from an external table.
|
||||
* @param msf The {@link AbstractMsf} to which the Stream belongs.
|
||||
* @param streamLength The byte length of the Stream.
|
||||
* stream length comes from an external table
|
||||
* @param msf the {@link Msf} to which the Stream belongs
|
||||
* @param streamLength the byte length of the Stream
|
||||
*/
|
||||
MsfStream(AbstractMsf msf, int streamLength) {
|
||||
MsfStream(Msf msf, int streamLength) {
|
||||
this.msf = msf;
|
||||
this.streamLength = streamLength;
|
||||
}
|
||||
|
@ -212,9 +209,9 @@ public class MsfStream {
|
|||
* map when it was previously stored in memory) from the bytes parameter starting at the
|
||||
* index offset and uses it to provide necessary information for the Stream to be usable.
|
||||
* Generally, deserialization is part of the step of loading the Stream information from
|
||||
* persistent storage (disk).
|
||||
* @param reader {@link PdbByteReader} from which to parse the information.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* persistent storage (disk)
|
||||
* @param reader {@link PdbByteReader} from which to parse the information
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
void deserializeStreamLengthAndMapTableAddress(PdbByteReader reader) throws PdbException {
|
||||
streamLength = reader.parseInt();
|
||||
|
@ -226,21 +223,20 @@ public class MsfStream {
|
|||
* Deserializes Stream page number information from the bytes parameter starting at the
|
||||
* index offset and uses it to provide necessary information for the Stream to be usable.
|
||||
* Generally, deserialization is part of the step of loading the Stream information from
|
||||
* persistent storage (disk).
|
||||
* @param reader {@link PdbByteReader} from which to parse the information.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* persistent storage (disc)
|
||||
* @param reader {@link PdbByteReader} from which to parse the information
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializePageNumbers(PdbByteReader reader, TaskMonitor monitor)
|
||||
void deserializePageNumbers(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
// This calculations works fine for streamLength = 0
|
||||
// and even streamLength = -1 (0xffffffff).
|
||||
int numPages =
|
||||
AbstractMsf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize());
|
||||
Msf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize());
|
||||
if (msf.getPageNumberSize() == 2) {
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
int pageNumber = reader.parseUnsignedShortVal();
|
||||
if (pageNumber == 0) {
|
||||
break;
|
||||
|
@ -250,7 +246,7 @@ public class MsfStream {
|
|||
}
|
||||
else if (msf.getPageNumberSize() == 4) {
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
int pageNumber = reader.parseInt();
|
||||
if (pageNumber == 0) {
|
||||
break;
|
||||
|
@ -264,18 +260,17 @@ public class MsfStream {
|
|||
* Deserializes Stream information from the bytes parameter starting at the index offset
|
||||
* and uses it to provide necessary information for the Stream to be usable.
|
||||
* Generally, deserialization is part of the step of loading the Stream information from
|
||||
* persistent storage (disk).
|
||||
* @param reader {@link PdbByteReader} from which to parse the information.
|
||||
* @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.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* persistent storage (disc)
|
||||
* @param reader {@link PdbByteReader} from which to parse the information
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializeStreamInfo(PdbByteReader reader, TaskMonitor monitor)
|
||||
void deserializeStreamInfo(PdbByteReader reader)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
deserializeStreamLengthAndMapTableAddress(reader);
|
||||
deserializePageNumbers(reader, monitor);
|
||||
deserializePageNumbers(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,45 +22,44 @@ import java.util.List;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents the the Stream Table used by the Multi-Stream Format File within
|
||||
* Windows PDB files.
|
||||
* We have intended to implement to the Microsoft PDB API (source); see the API for truth.
|
||||
*/
|
||||
abstract class AbstractMsfStreamTable {
|
||||
abstract class MsfStreamTable {
|
||||
|
||||
//==============================================================================================
|
||||
// Internals
|
||||
//==============================================================================================
|
||||
protected AbstractMsf msf;
|
||||
protected Msf msf;
|
||||
protected List<MsfStream> mapStreamNumberToStream;
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The {@link AbstractMsf} to which this class is associated.
|
||||
* Constructor
|
||||
* @param msf the {@link Msf} to which this class is associated
|
||||
*/
|
||||
AbstractMsfStreamTable(AbstractMsf msf) {
|
||||
MsfStreamTable(Msf msf) {
|
||||
this.msf = msf;
|
||||
mapStreamNumberToStream = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of streams in the stream table.
|
||||
* @return Number of streams.
|
||||
* Gets the number of streams in the stream table
|
||||
* @return number of streams
|
||||
*/
|
||||
int getNumStreams() {
|
||||
return mapStreamNumberToStream.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MsfStream} from the stream table indexed by the streamNumber.
|
||||
* @param streamNumber The number ID of the stream to retrieve.
|
||||
* @return {@link MsfStream} or {@code null} if no stream for the streamNumber.
|
||||
* Returns the {@link MsfStream} from the stream table indexed by the streamNumber
|
||||
* @param streamNumber the number ID of the stream to retrieve
|
||||
* @return {@link MsfStream} or {@code null} if no stream for the streamNumber
|
||||
*/
|
||||
MsfStream getStream(int streamNumber) {
|
||||
return mapStreamNumberToStream.get(streamNumber);
|
||||
|
@ -69,18 +68,17 @@ abstract class AbstractMsfStreamTable {
|
|||
/**
|
||||
* Loads Stream Table information from the serial stream contained in the Directory Stream.
|
||||
* @param directoryStream The {@link MsfStream} that contains the serial information to be
|
||||
* deserialized.
|
||||
* @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.
|
||||
* @throws PdbException Upon error with PDB format.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* deserialized
|
||||
* @throws IOException on file seek or read, invalid parameters, bad file configuration, or
|
||||
* inability to read required bytes
|
||||
* @throws PdbException upon error with PDB format
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserialize(MsfStream directoryStream, TaskMonitor monitor)
|
||||
void deserialize(MsfStream directoryStream)
|
||||
throws IOException, PdbException, CancelledException {
|
||||
// Read whole stream and then take selections from the byte array, as needed.
|
||||
int length = directoryStream.getLength();
|
||||
byte[] bytes = directoryStream.read(0, length, monitor);
|
||||
byte[] bytes = directoryStream.read(0, length);
|
||||
PdbByteReader reader = new PdbByteReader(bytes);
|
||||
|
||||
// V2.00 has short followed by an unused short. We will presume it 0x0000 and process all
|
||||
|
@ -91,7 +89,7 @@ abstract class AbstractMsfStreamTable {
|
|||
|
||||
// Get stream lengths and create streams.
|
||||
for (int streamNum = 0; streamNum < numStreams; streamNum++) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
int streamLength = reader.parseInt();
|
||||
parseExtraField(reader);
|
||||
MsfStream stream = new MsfStream(msf, streamLength);
|
||||
|
@ -100,35 +98,34 @@ abstract class AbstractMsfStreamTable {
|
|||
|
||||
// Populate the streams with their page information.
|
||||
for (int streamNum = 0; streamNum < numStreams; streamNum++) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
MsfStream stream = mapStreamNumberToStream.get(streamNum);
|
||||
if (stream != null) {
|
||||
stream.deserializePageNumbers(reader, monitor);
|
||||
stream.deserializePageNumbers(reader);
|
||||
}
|
||||
}
|
||||
|
||||
// Now replace the directoryStream in the table with the directoryStream taken from the
|
||||
// header, as it is more up-to-date than then entry in the table.
|
||||
setStream(msf.getDirectoryStreamNumber(), directoryStream, monitor);
|
||||
setStream(msf.getDirectoryStreamNumber(), directoryStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a {@link MsfStream} into the Stream Table at the index location. If the index location
|
||||
* does not exist, then enough dummy Streams are added to the table to allow the new
|
||||
* {@link MsfStream} to be added at the index location.
|
||||
* @param index The location (reference number) for the {@link MsfStream} to be added
|
||||
* (possibly as a replacement).
|
||||
* @param stream The {@link MsfStream} to be added or used to replace an existing Stream.
|
||||
* @param monitor {@link TaskMonitor} used for checking cancellation.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* {@link MsfStream} to be added at the index location
|
||||
* @param index the location (reference number) for the {@link MsfStream} to be added
|
||||
* (possibly as a replacement)
|
||||
* @param stream the {@link MsfStream} to be added or used to replace an existing Stream
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void setStream(int index, MsfStream stream, TaskMonitor monitor) throws CancelledException {
|
||||
void setStream(int index, MsfStream stream) throws CancelledException {
|
||||
if (index < mapStreamNumberToStream.size()) {
|
||||
mapStreamNumberToStream.set(index, stream);
|
||||
}
|
||||
else {
|
||||
for (int i = mapStreamNumberToStream.size(); i < index; i++) {
|
||||
monitor.checkCanceled();
|
||||
msf.checkCanceled();
|
||||
mapStreamNumberToStream.add(null);
|
||||
}
|
||||
mapStreamNumberToStream.add(stream);
|
||||
|
@ -147,15 +144,15 @@ abstract class AbstractMsfStreamTable {
|
|||
// Abstract Methods
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Abstract method to reads/parse extra field for each entry.
|
||||
* @param reader The {@link PdbByteReader} that contains the data/location to parse.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* Abstract method to reads/parse extra field for each entry
|
||||
* @param reader the {@link PdbByteReader} that contains the data/location to parse
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
*/
|
||||
protected abstract void parseExtraField(PdbByteReader reader) throws PdbException;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of MsfStreams allowed.
|
||||
* @return The maximum number of MsfStreams allowed.
|
||||
* Returns the maximum number of MsfStreams allowed
|
||||
* @return the maximum number of MsfStreams allowed
|
||||
*/
|
||||
protected abstract int getMaxNumStreamsAllowed();
|
||||
|
|
@ -19,18 +19,18 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsfStreamTable} for Microsoft v2.00 MSF.
|
||||
* This class is the version of {@link MsfStreamTable} for Microsoft v2.00 MSF.
|
||||
*/
|
||||
class MsfStreamTable200 extends AbstractMsfStreamTable {
|
||||
class MsfStreamTable200 extends MsfStreamTable {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The MSF associated for this class.
|
||||
* Constructor
|
||||
* @param msf the MSF associated for this class
|
||||
*/
|
||||
MsfStreamTable200(AbstractMsf msf) {
|
||||
MsfStreamTable200(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,18 +18,18 @@ package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
|
||||
|
||||
/**
|
||||
* This class is the version of {@link AbstractMsfStreamTable} for Microsoft v7.00 MSF.
|
||||
* This class is the version of {@link MsfStreamTable} for Microsoft v7.00 MSF.
|
||||
*/
|
||||
class MsfStreamTable700 extends AbstractMsfStreamTable {
|
||||
class MsfStreamTable700 extends MsfStreamTable {
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor.
|
||||
* @param msf The MSF associated for this class.
|
||||
* Constructor
|
||||
* @param msf the MSF associated for this class
|
||||
*/
|
||||
MsfStreamTable700(AbstractMsf msf) {
|
||||
MsfStreamTable700(Msf msf) {
|
||||
super(msf);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.*;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* This class represents the Discarded By Link symbol.
|
||||
|
@ -72,11 +71,11 @@ public class DiscardedByLinkMsSymbol extends AbstractMsSymbol {
|
|||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Constructor for this symbol.
|
||||
* @param pdb {@link AbstractPdb} to which this symbol belongs.
|
||||
* @param reader {@link PdbByteReader} from which this symbol is deserialized.
|
||||
* @throws PdbException Upon not enough data left to parse.
|
||||
* @throws CancelledException Upon user cancellation.
|
||||
* Constructor for this symbol
|
||||
* @param pdb {@link AbstractPdb} to which this symbol belongs
|
||||
* @param reader {@link PdbByteReader} from which this symbol is deserialized
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public DiscardedByLinkMsSymbol(AbstractPdb pdb, PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
|
@ -95,12 +94,12 @@ public class DiscardedByLinkMsSymbol extends AbstractMsSymbol {
|
|||
// SymbolParser parser = new SymbolParser(pdb);
|
||||
// symbolList = parser.deserializeSymbolRecords(dataReader);
|
||||
symbolList = getOrderedSymbols(
|
||||
SymbolRecords.deserializeSymbolRecords(pdb, dataReader, TaskMonitor.DUMMY));
|
||||
SymbolRecords.deserializeSymbolRecords(pdb, dataReader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of symbols in the order they were seen.
|
||||
* @return the list of symbols.
|
||||
* Returns the list of symbols in the order they were seen
|
||||
* @return the list of symbols
|
||||
*/
|
||||
private List<AbstractMsSymbol> getOrderedSymbols(Map<Long, AbstractMsSymbol> symbolsByOffset) {
|
||||
List<Long> offsets = new ArrayList<>(symbolsByOffset.keySet());
|
||||
|
|
|
@ -18,8 +18,8 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.AbstractTypeProgramInterface;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.TypeProgramInterface;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -51,15 +51,14 @@ public class ComplexTypeApplierMapper {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
void mapAppliers(TaskMonitor monitor) throws CancelledException {
|
||||
AbstractTypeProgramInterface typeProgramInterface =
|
||||
applicator.getPdb().getTypeProgramInterface();
|
||||
TypeProgramInterface typeProgramInterface = applicator.getPdb().getTypeProgramInterface();
|
||||
if (typeProgramInterface == null) {
|
||||
return;
|
||||
}
|
||||
int indexLimit = typeProgramInterface.getTypeIndexMaxExclusive();
|
||||
int indexNumber = typeProgramInterface.getTypeIndexMin();
|
||||
monitor.initialize(indexLimit - indexNumber);
|
||||
applicator.setMonitorMessage("PDB: Mapping Composites...");
|
||||
monitor.setMessage("PDB: Mapping Composites...");
|
||||
while (indexNumber < indexLimit) {
|
||||
monitor.checkCanceled();
|
||||
//PdbResearch.checkBreak(indexNumber);
|
||||
|
|
|
@ -52,13 +52,14 @@ import ghidra.util.task.TaskMonitor;
|
|||
* The class is to be constructed first.
|
||||
* <p>
|
||||
* The
|
||||
* {@link #applyTo(Program, DataTypeManager, Address, PdbApplicatorOptions, TaskMonitor, MessageLog)}
|
||||
* method is then called with the appropriate {@link PdbApplicatorOptions} along with a
|
||||
* {@link Program} and/or {@link DataTypeManager}. Either, but not both can be null.
|
||||
* {@link #applyTo(Program, DataTypeManager, Address, PdbApplicatorOptions, MessageLog)} method is
|
||||
* then called with the appropriate {@link PdbApplicatorOptions} along with
|
||||
* a {@link Program} and/or {@link DataTypeManager}. Either, but not both can be null.
|
||||
* If the Program is not null but the DatatypeManager is null, then the DataTypeManager is gotten
|
||||
* from the Program. If the Program is null, then data types can be applied to a DataTypeManager.
|
||||
* The validation logic for the parameters is found in
|
||||
* {@link #validateAndSetParameters(Program, DataTypeManager, Address, PdbApplicatorOptions, TaskMonitor, MessageLog)}.
|
||||
* {@link #validateAndSetParameters(Program, DataTypeManager, Address, PdbApplicatorOptions,
|
||||
* MessageLog)}.
|
||||
* <p>
|
||||
* Once the parameters are validated, appropriate classes and storage containers are constructed.
|
||||
* Then processing commences, first with data types, followed by symbol-related processing.
|
||||
|
@ -72,10 +73,10 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns integer value of BigInteger or Integer.MAX_VALUE if does not fit.
|
||||
* @param myApplicator PdbApplicator for which we are working.
|
||||
* @param big BigInteger value to convert.
|
||||
* @return the integer value.
|
||||
* Returns integer value of BigInteger or Long.MAX_VALUE if does not fit
|
||||
* @param myApplicator PdbApplicator for which we are working
|
||||
* @param big BigInteger value to convert
|
||||
* @return the integer value
|
||||
*/
|
||||
static long bigIntegerToLong(DefaultPdbApplicator myApplicator, BigInteger big) {
|
||||
try {
|
||||
|
@ -90,10 +91,10 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns integer value of BigInteger or Integer.MAX_VALUE if does not fit.
|
||||
* @param myApplicator PdbApplicator for which we are working.
|
||||
* @param big BigInteger value to convert.
|
||||
* @return the integer value.
|
||||
* Returns integer value of BigInteger or Integer.MAX_VALUE if does not fit
|
||||
* @param myApplicator PdbApplicator for which we are working
|
||||
* @param big BigInteger value to convert
|
||||
* @return the integer value
|
||||
*/
|
||||
static int bigIntegerToInt(DefaultPdbApplicator myApplicator, BigInteger big) {
|
||||
try {
|
||||
|
@ -108,7 +109,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
private String pdbFilename;
|
||||
private AbstractPdb pdb;
|
||||
|
||||
private PdbApplicatorMetrics pdbApplicatorMetrics;
|
||||
|
@ -118,7 +118,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
private PdbApplicatorOptions applicatorOptions;
|
||||
private MessageLog log;
|
||||
private TaskMonitor monitor;
|
||||
private CancelOnlyWrappingTaskMonitor cancelOnlyWrappingMonitor;
|
||||
|
||||
//==============================================================================================
|
||||
|
@ -165,11 +164,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
private Map<Integer, Set<RecordNumber>> recordNumbersByModuleNumber;
|
||||
|
||||
//==============================================================================================
|
||||
// TODO: eventually put access methods on AbstractPdb to get filename from it (deep down).
|
||||
public DefaultPdbApplicator(String pdbFilename, AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdbFilename, "pdbFilename cannot be null");
|
||||
public DefaultPdbApplicator(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
this.pdbFilename = pdbFilename;
|
||||
this.pdb = pdb;
|
||||
}
|
||||
|
||||
|
@ -177,29 +173,28 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Applies the PDB to the {@link Program} or {@link DataTypeManager}. Either, but not both,
|
||||
* can be null.
|
||||
* @param programParam The {@link Program} to which to apply the PDB. Can be null in certain
|
||||
* circumstances.
|
||||
* @param dataTypeManagerParam The {@link DataTypeManager} to which to apply data types. Can be
|
||||
* null in certain circumstances.
|
||||
* @param imageBaseParam Address bases from which symbol addresses are based. If null, uses
|
||||
* the image base of the program (both cannot be null).
|
||||
* @param applicatorOptionsParam {@link PdbApplicatorOptions} used for applying the PDB.
|
||||
* @param monitorParam TaskMonitor uses for watching progress and cancellation notices.
|
||||
* @param logParam The MessageLog to which to output messages.
|
||||
* @throws PdbException if there was a problem processing the data.
|
||||
* @throws CancelledException Upon user cancellation
|
||||
* can be null
|
||||
* @param programParam the {@link Program} to which to apply the PDB. Can be null in certain
|
||||
* circumstances
|
||||
* @param dataTypeManagerParam the {@link DataTypeManager} to which to apply data types. Can be
|
||||
* null in certain circumstances
|
||||
* @param imageBaseParam address bases from which symbol addresses are based. If null, uses
|
||||
* the image base of the program (both cannot be null)
|
||||
* @param applicatorOptionsParam {@link PdbApplicatorOptions} used for applying the PDB
|
||||
* @param logParam the MessageLog to which to output messages
|
||||
* @throws PdbException if there was a problem processing the data
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public void applyTo(Program programParam, DataTypeManager dataTypeManagerParam,
|
||||
Address imageBaseParam, PdbApplicatorOptions applicatorOptionsParam,
|
||||
TaskMonitor monitorParam, MessageLog logParam) throws PdbException, CancelledException {
|
||||
MessageLog logParam) throws PdbException, CancelledException {
|
||||
|
||||
// FIXME: should not support use of DataTypeManager-only since it will not have the correct data
|
||||
// organization if it corresponds to a data type archive. Need to evaulate archive use case
|
||||
// and determine if a program must always be used.
|
||||
// FIXME: should not support use of DataTypeManager-only since it will not have the correct
|
||||
// data organization if it corresponds to a data type archive. Need to evaluate archive
|
||||
// use case and determine if a program must always be used.
|
||||
|
||||
initializeApplyTo(programParam, dataTypeManagerParam, imageBaseParam,
|
||||
applicatorOptionsParam, monitorParam, logParam);
|
||||
applicatorOptionsParam, logParam);
|
||||
|
||||
switch (applicatorOptions.getProcessingControl()) {
|
||||
case DATA_TYPES_ONLY:
|
||||
|
@ -231,7 +226,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
private void processTypes() throws CancelledException, PdbException {
|
||||
setMonitorMessage("PDB: Applying to DTM " + dataTypeManager.getName() + "...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying to DTM " + dataTypeManager.getName() + "...");
|
||||
|
||||
PdbResearch.initBreakPointRecordNumbers(); // for developmental debug
|
||||
|
||||
|
@ -323,12 +319,12 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
private void initializeApplyTo(Program programParam, DataTypeManager dataTypeManagerParam,
|
||||
Address imageBaseParam, PdbApplicatorOptions applicatorOptionsParam,
|
||||
TaskMonitor monitorParam, MessageLog logParam) throws PdbException, CancelledException {
|
||||
MessageLog logParam) throws PdbException, CancelledException {
|
||||
|
||||
validateAndSetParameters(programParam, dataTypeManagerParam, imageBaseParam,
|
||||
applicatorOptionsParam, monitorParam, logParam);
|
||||
applicatorOptionsParam, logParam);
|
||||
|
||||
cancelOnlyWrappingMonitor = new CancelOnlyWrappingTaskMonitor(monitor);
|
||||
cancelOnlyWrappingMonitor = new CancelOnlyWrappingTaskMonitor(getMonitor());
|
||||
pdbApplicatorMetrics = new PdbApplicatorMetrics();
|
||||
|
||||
pdbPeHeaderInfoManager = new PdbPeHeaderInfoManager(this);
|
||||
|
@ -338,7 +334,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
pdbAddressManager = new PdbAddressManager(this, imageBase);
|
||||
|
||||
categoryUtils = setPdbCatogoryUtils(pdbFilename);
|
||||
categoryUtils = setPdbCatogoryUtils(pdb.getFilename());
|
||||
pdbPrimitiveTypeApplicator = new PdbPrimitiveTypeApplicator(dataTypeManager);
|
||||
typeApplierParser = new TypeApplierFactory(this);
|
||||
complexApplierMapper = new ComplexTypeApplierMapper(this);
|
||||
|
@ -367,8 +363,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
private void validateAndSetParameters(Program programParam,
|
||||
DataTypeManager dataTypeManagerParam, Address imageBaseParam,
|
||||
PdbApplicatorOptions applicatorOptionsParam, TaskMonitor monitorParam,
|
||||
MessageLog logParam) throws PdbException {
|
||||
PdbApplicatorOptions applicatorOptionsParam, MessageLog logParam) throws PdbException {
|
||||
applicatorOptions =
|
||||
(applicatorOptionsParam != null) ? applicatorOptionsParam : new PdbApplicatorOptions();
|
||||
if (programParam == null) {
|
||||
|
@ -386,7 +381,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
applicatorOptions.getProcessingControl());
|
||||
}
|
||||
}
|
||||
monitor = (monitorParam != null) ? monitorParam : TaskMonitor.DUMMY;
|
||||
log = (logParam != null) ? logParam : new MessageLog();
|
||||
program = programParam;
|
||||
dataTypeManager =
|
||||
|
@ -404,7 +398,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
int num = debugInfo.getNumModules();
|
||||
// moduleNumber zero is our global/public group.
|
||||
for (int moduleNumber = 0; moduleNumber <= num; moduleNumber++) {
|
||||
monitor.checkCanceled();
|
||||
checkCanceled();
|
||||
Map<Long, AbstractMsSymbol> symbols = debugInfo.getModuleSymbolsByOffset(moduleNumber);
|
||||
SymbolGroup symbolGroup = new SymbolGroup(symbols, moduleNumber);
|
||||
mySymbolGroups.add(symbolGroup);
|
||||
|
@ -416,8 +410,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
// Basic utility methods.
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Returns the {@link PdbApplicatorOptions} for this PdbApplicator.
|
||||
* @return the {@link PdbApplicatorOptions} for this PdbApplicator.
|
||||
* Returns the {@link PdbApplicatorOptions} for this PdbApplicator
|
||||
* @return the {@link PdbApplicatorOptions} for this PdbApplicator
|
||||
*/
|
||||
PdbApplicatorOptions getPdbApplicatorOptions() {
|
||||
return applicatorOptions;
|
||||
|
@ -428,15 +422,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
* @throws CancelledException if monitor has been cancelled
|
||||
*/
|
||||
void checkCanceled() throws CancelledException {
|
||||
monitor.checkCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message displayed on the task monitor
|
||||
* @param message the message to display
|
||||
*/
|
||||
void setMonitorMessage(String message) {
|
||||
monitor.setMessage(message);
|
||||
getMonitor().checkCanceled();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -448,7 +434,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the MessageLog.
|
||||
* Returns the MessageLog
|
||||
* @return the MessageLog
|
||||
*/
|
||||
MessageLog getMessageLog() {
|
||||
|
@ -483,34 +469,34 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link TaskMonitor} to available for this analyzer.
|
||||
* @return the monitor.
|
||||
* Returns the TaskMonitor
|
||||
* @return the monitor
|
||||
*/
|
||||
TaskMonitor getMonitor() {
|
||||
return monitor;
|
||||
public TaskMonitor getMonitor() {
|
||||
return pdb.getMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CancelOnlyWrappingTaskMonitor} to available for this analyzer. This is
|
||||
* useful for the user to be able to control the monitor progress bar without called commands
|
||||
* changing its progress on smaller tasks.
|
||||
* @return the monitor.
|
||||
* changing its progress on smaller tasks
|
||||
* @return the monitor
|
||||
*/
|
||||
TaskMonitor getCancelOnlyWrappingMonitor() {
|
||||
return cancelOnlyWrappingMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PdbApplicatorMetrics} being used for this applicator.
|
||||
* @return the {@link PdbApplicatorMetrics}.
|
||||
* Returns the {@link PdbApplicatorMetrics} being used for this applicator
|
||||
* @return the {@link PdbApplicatorMetrics}
|
||||
*/
|
||||
PdbApplicatorMetrics getPdbApplicatorMetrics() {
|
||||
return pdbApplicatorMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractPdb} being analyzed.
|
||||
* @return {@link AbstractPdb} being analyzed.
|
||||
* Returns the {@link AbstractPdb} being analyzed
|
||||
* @return {@link AbstractPdb} being analyzed
|
||||
*/
|
||||
@Override
|
||||
public AbstractPdb getPdb() {
|
||||
|
@ -518,8 +504,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Program} for which this analyzer is working.
|
||||
* @return {@link Program} for which this analyzer is working.
|
||||
* Returns the {@link Program} for which this analyzer is working
|
||||
* @return {@link Program} for which this analyzer is working
|
||||
*/
|
||||
@Override
|
||||
public Program getProgram() {
|
||||
|
@ -530,8 +516,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
// Information for a putative PdbTypeApplicator:
|
||||
|
||||
/**
|
||||
* Returns the {@link DataTypeManager} associated with this analyzer.
|
||||
* @return DataTypeManager which this analyzer is using.
|
||||
* Returns the {@link DataTypeManager} associated with this analyzer
|
||||
* @return DataTypeManager which this analyzer is using
|
||||
*/
|
||||
DataTypeManager getDataTypeManager() {
|
||||
return dataTypeManager;
|
||||
|
@ -551,10 +537,10 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Get the {@link CategoryPath} associated with the {@link SymbolPath} specified, rooting
|
||||
* it either at the PDB Category.
|
||||
* @param symbolPath Symbol path to be used to create the CategoryPath. Null represents global
|
||||
* namespace.
|
||||
* @return {@link CategoryPath} created for the input.
|
||||
* it either at the PDB Category
|
||||
* @param symbolPath symbol path to be used to create the CategoryPath. Null represents global
|
||||
* namespace
|
||||
* @return {@link CategoryPath} created for the input
|
||||
*/
|
||||
CategoryPath getCategory(SymbolPath symbolPath) {
|
||||
return categoryUtils.getCategory(symbolPath);
|
||||
|
@ -562,8 +548,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
/**
|
||||
* Returns the {@link CategoryPath} for a typedef with with the give {@link SymbolPath} and
|
||||
* module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()},
|
||||
* except that modeleNumber of 0 represents publics/globals.
|
||||
* module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()}
|
||||
* except that modeleNumber of 0 represents publics/globals
|
||||
* @param moduleNumber module number
|
||||
* @param symbolPath SymbolPath of the symbol
|
||||
* @return the CategoryPath
|
||||
|
@ -573,7 +559,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CategoryPath} for Anonymous Functions Category for the PDB.
|
||||
* Returns the {@link CategoryPath} for Anonymous Functions Category for the PDB
|
||||
* @return the {@link CategoryPath}
|
||||
*/
|
||||
CategoryPath getAnonymousFunctionsCategory() {
|
||||
|
@ -581,7 +567,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CategoryPath} for Anonymous Types Category for the PDB.
|
||||
* Returns the {@link CategoryPath} for Anonymous Types Category for the PDB
|
||||
* @return the {@link CategoryPath}
|
||||
*/
|
||||
CategoryPath getAnonymousTypesCategory() {
|
||||
|
@ -616,7 +602,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
int num = debugInfo.getNumModules();
|
||||
for (int index = 1; index <= num; index++) {
|
||||
monitor.checkCanceled();
|
||||
checkCanceled();
|
||||
String moduleName = debugInfo.getModuleInformation(index).getModuleName();
|
||||
categoryNames.add(moduleName);
|
||||
}
|
||||
|
@ -650,7 +636,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
List<MsTypeApplier> getVerticesInPostOrder() {
|
||||
setMonitorMessage("PDB: Determining data type dependency order...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Determining data type dependency order...");
|
||||
return GraphAlgorithms.getVerticesInPostOrder(applierDependencyGraph,
|
||||
GraphNavigator.topDownNavigator());
|
||||
}
|
||||
|
@ -686,7 +673,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
throw new PdbException("PDB: DebugInfo is null");
|
||||
}
|
||||
|
||||
for (AbstractSectionContribution sectionContribution : debugInfo
|
||||
for (SectionContribution sectionContribution : debugInfo
|
||||
.getSectionContributionList()) {
|
||||
int sectionContributionOffset = sectionContribution.getOffset();
|
||||
int maxSectionContributionOffset =
|
||||
|
@ -700,13 +687,14 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
private void processDataTypesSequentially() throws CancelledException, PdbException {
|
||||
AbstractTypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
TypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
if (tpi == null) {
|
||||
return;
|
||||
}
|
||||
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(num);
|
||||
setMonitorMessage("PDB: Processing " + num + " data type components...");
|
||||
monitor.setMessage("PDB: Processing " + num + " data type components...");
|
||||
for (int indexNumber =
|
||||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||
monitor.checkCanceled();
|
||||
|
@ -767,13 +755,14 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
private void processItemTypesSequentially() throws CancelledException, PdbException {
|
||||
AbstractTypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
TypeProgramInterface ipi = pdb.getItemProgramInterface();
|
||||
if (ipi == null) {
|
||||
return;
|
||||
}
|
||||
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(num);
|
||||
setMonitorMessage("PDB: Processing " + num + " item type components...");
|
||||
monitor.setMessage("PDB: Processing " + num + " item type components...");
|
||||
for (int indexNumber =
|
||||
ipi.getTypeIndexMin(); indexNumber < ipi.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||
monitor.checkCanceled();
|
||||
|
@ -792,8 +781,9 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
private void processDeferred() throws CancelledException, PdbException {
|
||||
List<MsTypeApplier> verticesInPostOrder = getVerticesInPostOrder();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(verticesInPostOrder.size());
|
||||
setMonitorMessage("PDB: Processing " + verticesInPostOrder.size() +
|
||||
monitor.setMessage("PDB: Processing " + verticesInPostOrder.size() +
|
||||
" deferred data type dependencies...");
|
||||
for (MsTypeApplier applier : verticesInPostOrder) {
|
||||
monitor.checkCanceled();
|
||||
|
@ -808,13 +798,14 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
private void resolveSequentially() throws CancelledException {
|
||||
AbstractTypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
TypeProgramInterface tpi = pdb.getTypeProgramInterface();
|
||||
if (tpi == null) {
|
||||
return;
|
||||
}
|
||||
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(num);
|
||||
setMonitorMessage("PDB: Resolving " + num + " data type components...");
|
||||
monitor.setMessage("PDB: Resolving " + num + " data type components...");
|
||||
long longStart = System.currentTimeMillis();
|
||||
for (int indexNumber =
|
||||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||
|
@ -869,10 +860,10 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
/**
|
||||
* Returns true if the {@link Address} is an invalid address for continuing application of
|
||||
* information to the program. Will report Error or message for an invalid address and will
|
||||
* report a "External address" message for the name when the address is external.
|
||||
* report a "External address" message for the name when the address is external
|
||||
* @param address the address to test
|
||||
* @param name name associated with the address used for reporting error/info situations.
|
||||
* @return {@code true} if the address should be processed.
|
||||
* @param name name associated with the address used for reporting error/info situations
|
||||
* @return {@code true} if the address should be processed
|
||||
*/
|
||||
boolean isInvalidAddress(Address address, String name) {
|
||||
if (address == PdbAddressManager.BAD_ADDRESS) {
|
||||
|
@ -899,30 +890,30 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the Address for the given section and offset.
|
||||
* @param symbol The {@link AddressMsSymbol}
|
||||
* @return The Address, which can be {@code Address.NO_ADDRESS} if invalid or
|
||||
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program.
|
||||
* Returns the Address for the given section and offset
|
||||
* @param symbol the {@link AddressMsSymbol}
|
||||
* @return the Address, which can be {@code Address.NO_ADDRESS} if invalid or
|
||||
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program
|
||||
*/
|
||||
Address getAddress(AddressMsSymbol symbol) {
|
||||
return pdbAddressManager.getAddress(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Address for the given section and offset.
|
||||
* @param segment The segment
|
||||
* @param offset The offset
|
||||
* @return The Address
|
||||
* Returns the Address for the given section and offset
|
||||
* @param segment the segment
|
||||
* @param offset the offset
|
||||
* @return the Address
|
||||
*/
|
||||
Address getAddress(int segment, long offset) {
|
||||
return pdbAddressManager.getRawAddress(segment, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Address for the given section and offset.
|
||||
* Returns the Address for the given section and offset
|
||||
* @param symbol The {@link AddressMsSymbol}
|
||||
* @return The Address, which can be {@code Address.NO_ADDRESS} if invalid or
|
||||
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program.
|
||||
* @return the Address, which can be {@code Address.NO_ADDRESS} if invalid or
|
||||
* {@code Address.EXTERNAL_ADDRESS} if the address is external to the program
|
||||
*/
|
||||
Address getRawAddress(AddressMsSymbol symbol) {
|
||||
return pdbAddressManager.getRawAddress(symbol);
|
||||
|
@ -933,7 +924,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
* associated address. This allows the PdbAddressManager to create and organize the
|
||||
* re-mapped address and supply them. Also returns the address of the pre-existing symbol
|
||||
* of the same name if the name was unique, otherwise null if it didn't exist or wasn't
|
||||
* unique.
|
||||
* unique
|
||||
* @param name the symbol name
|
||||
* @param address its associated address
|
||||
* @return the {@link Address} of existing symbol or null
|
||||
|
@ -946,7 +937,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
* Returns the Address of an existing symbol for the query address, where the mapping is
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself
|
||||
* @param address the query address
|
||||
* @return the remapAddress
|
||||
*/
|
||||
|
@ -989,8 +980,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get CLI metadata for specified tableNum and rowNum within the CLI
|
||||
* metadata stream.
|
||||
* Get CLI metadata for specified tableNum and rowNum within the CLI metadata stream
|
||||
* @param tableNum CLI metadata stream table index
|
||||
* @param rowNum table row number
|
||||
* @return CLI metadata or null if specified tableNum not found
|
||||
|
@ -1021,7 +1011,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
/**
|
||||
* Process all symbols. User should not then call other methods:
|
||||
* {@link #processGlobalSymbolsNoTypedefs()}, (@link #processPublicSymbols()}, and
|
||||
* {@link #processNonPublicOrGlobalSymbols()}.
|
||||
* {@link #processNonPublicOrGlobalSymbols()}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon issue processing the request
|
||||
*/
|
||||
|
@ -1039,7 +1029,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
return;
|
||||
}
|
||||
int totalCount = symbolGroup.size();
|
||||
setMonitorMessage("PDB: Applying " + totalCount + " main symbol components...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying " + totalCount + " main symbol components...");
|
||||
monitor.initialize(totalCount);
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
processSymbolGroup(0, iter);
|
||||
|
@ -1054,6 +1045,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
int totalCount = 0;
|
||||
int num = debugInfo.getNumModules();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
for (int moduleNumber = 1; moduleNumber <= num; moduleNumber++) {
|
||||
monitor.checkCanceled();
|
||||
SymbolGroup symbolGroup = getSymbolGroupForModule(moduleNumber);
|
||||
|
@ -1062,7 +1054,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
totalCount += symbolGroup.size();
|
||||
}
|
||||
setMonitorMessage("PDB: Applying " + totalCount + " module symbol components...");
|
||||
monitor.setMessage("PDB: Applying " + totalCount + " module symbol components...");
|
||||
monitor.initialize(totalCount);
|
||||
|
||||
// Process symbols list for each module
|
||||
|
@ -1098,6 +1090,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
private void processSymbolGroup(int moduleNumber, AbstractMsSymbolIterator iter)
|
||||
throws CancelledException {
|
||||
iter.initGet();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
while (iter.hasNext()) {
|
||||
monitor.checkCanceled();
|
||||
procSym(iter);
|
||||
|
@ -1108,8 +1101,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Process public symbols. User should not then call {@link #processAllSymbols()}; but
|
||||
* has these other methods available to supplement this one: {@link #processGlobalSymbolsNoTypedefs()}
|
||||
* and {@link #processNonPublicOrGlobalSymbols()}.
|
||||
* has these other methods available to supplement this one:
|
||||
* {@link #processGlobalSymbolsNoTypedefs()} and {@link #processNonPublicOrGlobalSymbols()}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon issue processing the request
|
||||
*/
|
||||
|
@ -1127,7 +1120,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
setMonitorMessage("PDB: Applying " + offsets.size() + " public symbol components...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying " + offsets.size() + " public symbol components...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
@ -1146,7 +1140,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
/**
|
||||
* Process global symbols--no typedef. User should not then call {@link #processAllSymbols()};
|
||||
* but has these other methods available to supplement this one: (@link #processPublicSymbols()}
|
||||
* and {@link #processNonPublicOrGlobalSymbols()}.
|
||||
* and {@link #processNonPublicOrGlobalSymbols()}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon issue processing the request
|
||||
*/
|
||||
|
@ -1164,7 +1158,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
setMonitorMessage("PDB: Applying global symbols...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying global symbols...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
@ -1184,7 +1179,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Process global typdef symbols.
|
||||
* Process global typdef symbols
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon issue processing the request
|
||||
*/
|
||||
|
@ -1202,7 +1197,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
setMonitorMessage("PDB: Applying typedefs...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying typedefs...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
@ -1223,7 +1219,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
/**
|
||||
* Processing non-public, non-global symbols. User should not then call
|
||||
* {@link #processAllSymbols()}; but has these other methods available to supplement this one:
|
||||
* {@link #processGlobalSymbolsNoTypedefs()} and (@link #processPublicSymbols()}.
|
||||
* {@link #processGlobalSymbolsNoTypedefs()} and (@link #processPublicSymbols()}
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws PdbException upon issue processing the request
|
||||
*/
|
||||
|
@ -1239,6 +1235,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
return;
|
||||
}
|
||||
|
||||
TaskMonitor monitor = getMonitor();
|
||||
Set<Long> offsetsRemaining = symbolGroup.getOffsets();
|
||||
for (long off : debugInfo.getPublicSymbolInformation()
|
||||
.getModifiedHashRecordSymbolOffsets()) {
|
||||
|
@ -1251,7 +1248,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
offsetsRemaining.remove(off);
|
||||
}
|
||||
|
||||
setMonitorMessage(
|
||||
monitor.setMessage(
|
||||
"PDB: Applying " + offsetsRemaining.size() + " other symbol components...");
|
||||
monitor.initialize(offsetsRemaining.size());
|
||||
//getCategoryUtils().setModuleTypedefsCategory(null);
|
||||
|
@ -1275,7 +1272,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||
if (debugInfo != null) {
|
||||
int num = 1;
|
||||
for (AbstractModuleInformation module : debugInfo.getModuleInformationList()) {
|
||||
for (ModuleInformation module : debugInfo.getModuleInformationList()) {
|
||||
if (isLinkerModule(module.getModuleName())) {
|
||||
return num;
|
||||
}
|
||||
|
@ -1300,12 +1297,13 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
return false;
|
||||
}
|
||||
|
||||
setMonitorMessage("PDB: Applying " + symbolGroup.size() + " linker symbol components...");
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.setMessage("PDB: Applying " + symbolGroup.size() + " linker symbol components...");
|
||||
monitor.initialize(symbolGroup.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
while (iter.hasNext()) {
|
||||
checkCanceled();
|
||||
monitor.checkCanceled();
|
||||
pdbApplicatorMetrics.witnessLinkerSymbolType(iter.peek());
|
||||
procSym(iter);
|
||||
monitor.incrementProgress(1);
|
||||
|
@ -1340,12 +1338,13 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
SymbolGroup symbolGroup = getSymbolGroupForModule(linkerModuleNumber);
|
||||
if (symbolGroup != null) {
|
||||
|
||||
getMonitor().initialize(symbolGroup.size());
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(symbolGroup.size());
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
int numCompileSymbols = 0;
|
||||
int compileSymbolNumForCoffSymbols = -1;
|
||||
while (iter.hasNext()) {
|
||||
checkCanceled();
|
||||
monitor.checkCanceled();
|
||||
AbstractMsSymbol symbol = iter.next();
|
||||
getPdbApplicatorMetrics().witnessLinkerSymbolType(symbol);
|
||||
if (symbol instanceof PeCoffSectionMsSymbol) {
|
||||
|
@ -1396,6 +1395,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
|
||||
int totalCount = 0;
|
||||
int num = debugInfo.getNumModules();
|
||||
TaskMonitor monitor = getMonitor();
|
||||
for (int index = 1; index <= num; index++) {
|
||||
monitor.checkCanceled();
|
||||
if (index == linkerModuleNumber) {
|
||||
|
@ -1407,7 +1407,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
}
|
||||
totalCount += symbolGroup.size();
|
||||
}
|
||||
setMonitorMessage("PDB: Processing module thunks...");
|
||||
monitor.setMessage("PDB: Processing module thunks...");
|
||||
monitor.initialize(totalCount);
|
||||
|
||||
// Process symbols list for each module
|
||||
|
@ -1475,8 +1475,9 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
|||
//==============================================================================================
|
||||
private void defineClasses() throws CancelledException {
|
||||
// create namespace and classes in an ordered fashion use tree map
|
||||
TaskMonitor monitor = getMonitor();
|
||||
monitor.initialize(isClassByNamespace.size());
|
||||
setMonitorMessage("PDB: Defining classes...");
|
||||
monitor.setMessage("PDB: Defining classes...");
|
||||
for (Map.Entry<SymbolPath, Boolean> entry : isClassByNamespace.entrySet()) {
|
||||
monitor.checkCanceled();
|
||||
SymbolPath path = entry.getKey();
|
||||
|
|
|
@ -31,11 +31,11 @@ public class NestedTypeApplier extends MsTypeApplier {
|
|||
private MsTypeApplier nestedTypeDefinitionApplier = null;
|
||||
|
||||
/**
|
||||
* Constructor for nested type applier.
|
||||
* @param applicator {@link DefaultPdbApplicator} for which this class is working.
|
||||
* Constructor for nested type applier
|
||||
* @param applicator {@link DefaultPdbApplicator} for which this class is working
|
||||
* @param msType {@link AbstractNestedTypeMsType} or {@link AbstractNestedTypeExtMsType} to
|
||||
* process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
* process
|
||||
* @throws IllegalArgumentException upon invalid arguments
|
||||
*/
|
||||
public NestedTypeApplier(DefaultPdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
|
@ -51,8 +51,8 @@ public class NestedTypeApplier extends MsTypeApplier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this nested type.
|
||||
* @return Name of the nested type.
|
||||
* Returns the name of this nested type
|
||||
* @return name of the nested type
|
||||
*/
|
||||
String getTypeName() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
|
@ -62,8 +62,8 @@ public class NestedTypeApplier extends MsTypeApplier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the nested (member?) name for this nested type.
|
||||
* @return (Member?) Name for the nested type.
|
||||
* Returns the nested (member?) name for this nested type
|
||||
* @return (member?) name for the nested type
|
||||
*/
|
||||
String getMemberName() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
|
@ -87,8 +87,8 @@ public class NestedTypeApplier extends MsTypeApplier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicates if there are attributes. Returns false if not "applied" yet.
|
||||
* @return [@code true} if there are attributes.
|
||||
* Indicates if there are attributes. Returns false if not "applied" yet
|
||||
* @return {@code true} if there are attributes
|
||||
*/
|
||||
boolean hasAttributes() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
|
@ -101,8 +101,8 @@ public class NestedTypeApplier extends MsTypeApplier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the attributes if they exist.
|
||||
* @return the attributes or null if they do not exist.
|
||||
* Returns the attributes if they exist
|
||||
* @return the attributes or null if they do not exist
|
||||
*/
|
||||
ClassFieldMsAttributes getAttributes() {
|
||||
AbstractMsType type = nestedTypeDefinitionApplier.getMsType();
|
||||
|
|
|
@ -34,19 +34,19 @@ import ghidra.util.exception.CancelledException;
|
|||
public interface PdbApplicator {
|
||||
|
||||
/**
|
||||
* Returns the {@link AbstractPdb} being analyzed.
|
||||
* @return {@link AbstractPdb} being analyzed.
|
||||
* Returns the {@link AbstractPdb} being analyzed
|
||||
* @return {@link AbstractPdb} being analyzed
|
||||
*/
|
||||
public AbstractPdb getPdb();
|
||||
|
||||
/**
|
||||
* Returns the {@link Program} for which this analyzer is working.
|
||||
* @return {@link Program} for which this analyzer is working.
|
||||
* Returns the {@link Program} for which this analyzer is working
|
||||
* @return {@link Program} for which this analyzer is working
|
||||
*/
|
||||
Program getProgram();
|
||||
|
||||
/**
|
||||
* Returns the original image base value from the PE Header.
|
||||
* Returns the original image base value from the PE Header
|
||||
* @return the original image base for the binary
|
||||
*/
|
||||
public long getOriginalImageBase();
|
||||
|
@ -60,7 +60,7 @@ public interface PdbApplicator {
|
|||
|
||||
/**
|
||||
* Returns the compile symbol seen in the "Linker" module. Should be one of
|
||||
* {@link Compile3MsSymbol} or {@link AbstractCompile2MsSymbol}.
|
||||
* {@link Compile3MsSymbol} or {@link AbstractCompile2MsSymbol}
|
||||
* @return the compile symbol
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
|
|
|
@ -334,8 +334,9 @@ 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)) {
|
||||
|
@ -424,7 +425,7 @@ public class PdbResearch {
|
|||
|
||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
applicator.setMonitorMessage("PDB: Applying typedefs...");
|
||||
monitor.setMessage("PDB: Applying typedefs...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
@ -641,7 +642,7 @@ public class PdbResearch {
|
|||
|
||||
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
applicator.setMonitorMessage(
|
||||
monitor.setMessage(
|
||||
"PDB: Applying " + offsets.size() + " public symbol components...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
|
@ -676,7 +677,7 @@ public class PdbResearch {
|
|||
|
||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
applicator.setMonitorMessage("PDB: Applying global symbols...");
|
||||
monitor.setMessage("PDB: Applying global symbols...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
@ -712,7 +713,7 @@ public class PdbResearch {
|
|||
}
|
||||
totalCount += symbolGroup.size();
|
||||
}
|
||||
applicator.setMonitorMessage(
|
||||
monitor.setMessage(
|
||||
"PDB: Applying " + totalCount + " module symbol components...");
|
||||
monitor.initialize(totalCount);
|
||||
|
||||
|
@ -900,7 +901,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();
|
||||
}
|
||||
}
|
||||
|
@ -945,7 +947,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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class PdbVbtManager extends VbtManager {
|
|||
|
||||
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||
List<Long> offsets = publicSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||
applicator.setMonitorMessage("PDB: Searching for virtual base table symbols...");
|
||||
monitor.setMessage("PDB: Searching for virtual base table symbols...");
|
||||
monitor.initialize(offsets.size());
|
||||
|
||||
AbstractMsSymbolIterator iter = symbolGroup.iterator();
|
||||
|
|
|
@ -144,11 +144,11 @@ class LoadPdbTask extends Task {
|
|||
try (AbstractPdb pdb = ghidra.app.util.bin.format.pdb2.pdbreader.PdbParser.parse(
|
||||
pdbFile.getAbsolutePath(), pdbReaderOptions, monitor)) {
|
||||
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
||||
pdb.deserialize(monitor);
|
||||
pdb.deserialize();
|
||||
DefaultPdbApplicator applicator =
|
||||
new DefaultPdbApplicator(pdbFile.getAbsolutePath(), pdb);
|
||||
new DefaultPdbApplicator(pdb);
|
||||
applicator.applyTo(program, program.getDataTypeManager(), program.getImageBase(),
|
||||
pdbApplicatorOptions, monitor, log);
|
||||
pdbApplicatorOptions, log);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -33,17 +33,13 @@ public class DummyPdb700 extends Pdb700 {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a basic object.
|
||||
* Note: not all values are initialized. Constructor for a dummy PDB used for testing.
|
||||
* @param tpiIndexMin int. The IndexMin to set/use for the
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* @param tpiIndexMaxExclusive int. MaxIndex+1 to set/use for the
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* @param ipiIndexMin int. The IndexMin to set/use for the
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* @param ipiIndexMaxExclusive int. MaxIndex+1 to set/use for the
|
||||
* {@link AbstractTypeProgramInterface}.
|
||||
* @throws IOException Upon file IO seek/read issues.
|
||||
* @throws PdbException Upon unknown value for configuration or error in processing components.
|
||||
* Note: not all values are initialized. Constructor for a dummy PDB used for testing
|
||||
* @param tpiIndexMin int. The IndexMin to set/use for the {@link TypeProgramInterface}
|
||||
* @param tpiIndexMaxExclusive int. MaxIndex+1 to set/use for the {@link TypeProgramInterface}
|
||||
* @param ipiIndexMin int. The IndexMin to set/use for the {@link TypeProgramInterface}
|
||||
* @param ipiIndexMaxExclusive int. MaxIndex+1 to set/use for the {@link TypeProgramInterface}
|
||||
* @throws IOException upon file IO seek/read issues
|
||||
* @throws PdbException upon unknown value for configuration or error in processing components
|
||||
*/
|
||||
public DummyPdb700(int tpiIndexMin, int tpiIndexMaxExclusive, int ipiIndexMin,
|
||||
int ipiIndexMaxExclusive) throws IOException, PdbException {
|
||||
|
@ -58,9 +54,9 @@ public class DummyPdb700 extends Pdb700 {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set true to make existing debug information available; when set false {@link #getDebugInfo()}
|
||||
* returns null (as though it does not exist)
|
||||
* @param setAvailable true to return actual value; false to have it return null
|
||||
* Set @code true} to make existing debug information available; when set false,
|
||||
* {@link #getDebugInfo()} returns null (as though it does not exist)
|
||||
* @param setAvailable {@code true} to return actual value; @code false} to have it return null
|
||||
*/
|
||||
public void setDebugInfoAvailable(boolean setAvailable) {
|
||||
debugInfoAvailable = setAvailable;
|
||||
|
@ -73,10 +69,10 @@ public class DummyPdb700 extends Pdb700 {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a "type" record for a
|
||||
* particular record number.
|
||||
* @param recordNumber int record number for the "type" AbstractMsType to be inserted.
|
||||
* @param type AbstractMsType to be inserted.
|
||||
* @return boolean true if successful.
|
||||
* particular record number
|
||||
* @param recordNumber record number for the "type" AbstractMsType to be inserted
|
||||
* @param type AbstractMsType to be inserted
|
||||
* @return {@code true} if successful
|
||||
*/
|
||||
public boolean setTypeRecord(int recordNumber, AbstractMsType type) {
|
||||
return typeProgramInterface.setRecord(recordNumber, type);
|
||||
|
@ -84,9 +80,9 @@ public class DummyPdb700 extends Pdb700 {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to add a "type" record that gets
|
||||
* its record number automatically assigned.
|
||||
* @param type "type" AbstractMsType to be inserted.
|
||||
* @return int record number assigned.
|
||||
* its record number automatically assigned
|
||||
* @param type "type" AbstractMsType to be inserted
|
||||
* @return record number assigned
|
||||
*/
|
||||
public int addTypeRecord(AbstractMsType type) {
|
||||
return typeProgramInterface.addRecord(type);
|
||||
|
@ -94,10 +90,10 @@ public class DummyPdb700 extends Pdb700 {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to set a "item" record for a
|
||||
* particular record number.
|
||||
* @param recordNumber int record number for the "item" AbstractMsType to be inserted.
|
||||
* @param type AbstractMsType to be inserted.
|
||||
* @return boolean true if successful.
|
||||
* particular record number
|
||||
* @param recordNumber record number for the "item" AbstractMsType to be inserted
|
||||
* @param type AbstractMsType to be inserted
|
||||
* @return {@code true} if successful
|
||||
*/
|
||||
public boolean setItemRecord(int recordNumber, AbstractMsType type) {
|
||||
return itemProgramInterface.setRecord(recordNumber, type);
|
||||
|
@ -105,9 +101,9 @@ public class DummyPdb700 extends Pdb700 {
|
|||
|
||||
/**
|
||||
* IMPORTANT: This method is for testing only. It allows us to add a "item" record that gets
|
||||
* its record number automatically assigned.
|
||||
* @param type "item" AbstractMsType to be inserted.
|
||||
* @return int record number assigned.
|
||||
* its record number automatically assigned
|
||||
* @param type "item" AbstractMsType to be inserted
|
||||
* @return record number assigned
|
||||
*/
|
||||
public int addItemRecord(AbstractMsType type) {
|
||||
return itemProgramInterface.addRecord(type);
|
||||
|
|
|
@ -57,7 +57,7 @@ public class MsfReaderUnitTest extends AbstractGenericTest {
|
|||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* @throws IOException Upon file IO issues.
|
||||
* @throws IOException Upon file IO issues
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void setUp() throws IOException {
|
||||
|
@ -90,13 +90,13 @@ public class MsfReaderUnitTest extends AbstractGenericTest {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Dumps a number bytes of information from a Stream in the AbstractStreamFile to String.
|
||||
* for debug purposes.
|
||||
* @param streamFile The AbstractStreamFile to be used.
|
||||
* @param streamNumber The streamNumber of the file to dump.
|
||||
* @param maxOut Maximum number of bytes to dump.
|
||||
* @return String containing the output.
|
||||
* for debug purposes
|
||||
* @param streamFile the AbstractStreamFile to be used
|
||||
* @param streamNumber the streamNumber of the file to dump
|
||||
* @param maxOut maximum number of bytes to dump
|
||||
* @return string containing the output
|
||||
*/
|
||||
public static String dumpStream(AbstractMsf streamFile, int streamNumber, int maxOut) {
|
||||
public static String dumpStream(Msf streamFile, int streamNumber, int maxOut) {
|
||||
MsfStream stream = streamFile.getStream(streamNumber);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Stream: " + streamNumber + "\n");
|
||||
|
@ -109,7 +109,7 @@ public class MsfReaderUnitTest extends AbstractGenericTest {
|
|||
//==============================================================================================
|
||||
@Test
|
||||
public void testStreamFile200Header() {
|
||||
try (AbstractMsf streamFile =
|
||||
try (Msf streamFile =
|
||||
MsfParser.parse(testFileName200, new PdbReaderOptions(), TaskMonitor.DUMMY)) {
|
||||
int numStreams = streamFile.getNumStreams();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -127,7 +127,7 @@ public class MsfReaderUnitTest extends AbstractGenericTest {
|
|||
|
||||
@Test
|
||||
public void testStreamFile700Header() {
|
||||
try (AbstractMsf streamFile =
|
||||
try (Msf streamFile =
|
||||
MsfParser.parse(testFileName700, new PdbReaderOptions(), TaskMonitor.DUMMY)) {
|
||||
int numStreams = streamFile.getNumStreams();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue