mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-08-28 05:20:21 +00:00
Merge remote-tracking branch 'origin/GP-2367_ghizard_PDB_U_cleanup_refactor_rename_itfc_changes--SQUASHED'
This commit is contained in:
commit
75a87036e6
|
@ -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) {
|
||||
|
@ -113,21 +112,20 @@ public class NameTable {
|
|||
//==============================================================================================
|
||||
// TODO: Regarding String conversions... We expect that US_ASCII could be a problem, but it
|
||||
// is probably better than creating the String without any code set chosen at all. Do we
|
||||
// need to change all processing of Strings within the PDB so that we are only creating byte
|
||||
// need to change all processing of Strings within the PDB so that we are only creating byte
|
||||
// arrays with some notional idea (1 byte, 2 byte, possibly utf-8, utf-16, wchar_t, or
|
||||
// "unknown" and defer true interpretation/conversion to String until we know or until
|
||||
// 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);
|
||||
// PublicSymbolInformation (hash), as they are both are search mechanisms.
|
||||
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;
|
||||
|
@ -60,7 +61,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
* Number of Pages Number of pages 2 4 int
|
||||
* currently used
|
||||
* in the file
|
||||
* Serialized Sequence of page
|
||||
* Serialized Sequence of page
|
||||
* info about numbers
|
||||
* directory
|
||||
* stream:
|
||||
|
@ -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,39 +44,38 @@ 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.
|
||||
deserializeStreamLengthAndMapTableAddress(reader);
|
||||
// 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.
|
||||
// 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,14 +20,13 @@ 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
|
||||
* This class was crafted to take the place of the formal Free Page Map in a complete
|
||||
* (read/write/modify) solution, but might not need to be used for a "reader" technology.
|
||||
* <P>
|
||||
* NOTE: This implementation is incomplete: we are not processing or accessing the bits yet.
|
||||
|
@ -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…
Reference in a new issue