mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 05:32:14 +00:00
Merge remote-tracking branch 'origin/GP-3714_ghizard_investigate_random_access_datatype_records--SQUASHED'
This commit is contained in:
commit
0a2b9f6fd1
@ -169,8 +169,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public void deserialize()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
public void deserialize() throws IOException, PdbException, CancelledException {
|
||||
// msf should only be null for testing versions of PDB.
|
||||
if (msf == null) {
|
||||
return;
|
||||
@ -330,6 +329,8 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
recordNumber = fixupTypeIndex(recordNumber, typeClass);
|
||||
AbstractMsType msType =
|
||||
getTPI(recordNumber.getCategory()).getRecord(recordNumber.getNumber());
|
||||
// AbstractMsType msType =
|
||||
// getTPI(recordNumber.getCategory()).getRandomAccessRecord(recordNumber.getNumber());
|
||||
if (!typeClass.isInstance(msType)) {
|
||||
if (!recordNumber.isNoType()) {
|
||||
PdbLog.logGetTypeClassMismatch(msType, typeClass);
|
||||
@ -494,8 +495,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
* @throws PdbException upon error in processing components
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializeSubstreams()
|
||||
throws IOException, PdbException, CancelledException {
|
||||
void deserializeSubstreams() throws IOException, PdbException, CancelledException {
|
||||
|
||||
if (substreamsDeserialized) {
|
||||
return;
|
||||
@ -594,8 +594,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
* @throws PdbException upon error parsing a field
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
abstract void deserializeDirectory()
|
||||
throws IOException, PdbException, CancelledException;
|
||||
abstract void deserializeDirectory() throws IOException, PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Dumps the PDB Directory to {@link Writer}. This package-protected method is for
|
||||
@ -616,8 +615,7 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
protected PdbByteReader getDirectoryReader()
|
||||
throws IOException, CancelledException {
|
||||
protected PdbByteReader getDirectoryReader() throws IOException, CancelledException {
|
||||
return getReaderForStreamNumber(PDB_DIRECTORY_STREAM_NUMBER, 0,
|
||||
MsfStream.MAX_STREAM_LENGTH);
|
||||
}
|
||||
|
@ -23,4 +23,11 @@ public interface TPI {
|
||||
int getTypeIndexMaxExclusive();
|
||||
|
||||
AbstractMsType getRecord(int recordNumber);
|
||||
|
||||
/**
|
||||
* Random access of {@link AbstractMsType} record indicated by {@code recordNumber}
|
||||
* @param recordNumber record number of the record to retrieve
|
||||
* @return {@link AbstractMsType} pertaining to the record number
|
||||
*/
|
||||
AbstractMsType getRandomAccessRecord(int recordNumber);
|
||||
}
|
||||
|
@ -59,6 +59,10 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
|
||||
protected int versionNumber = 0;
|
||||
|
||||
private record OffLen(int offset, int length) {}; // record type for quick random access
|
||||
|
||||
private List<OffLen> offLenRecords;
|
||||
|
||||
//==============================================================================================
|
||||
// API
|
||||
//==============================================================================================
|
||||
@ -68,8 +72,7 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
* @param recordCategory the RecordCategory of these records
|
||||
* @param streamNumber the stream number that contains the {@link TypeProgramInterface} data
|
||||
*/
|
||||
public TypeProgramInterface(AbstractPdb pdb, RecordCategory recordCategory,
|
||||
int streamNumber) {
|
||||
public TypeProgramInterface(AbstractPdb pdb, RecordCategory recordCategory, int streamNumber) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
this.pdb = pdb;
|
||||
this.recordCategory = recordCategory;
|
||||
@ -142,6 +145,40 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
return typeList.get(recordNumber - typeIndexMin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractMsType getRandomAccessRecord(int recordNumber) {
|
||||
if (recordNumber < 0 || recordNumber - typeIndexMin > typeList.size()) {
|
||||
// This should not happen, but we have seen it and cannot yet explain it.
|
||||
// So, for now, we are creating and returning a new BadMsType.
|
||||
PdbLog.logBadTypeRecordIndex(this, recordNumber);
|
||||
BadMsType type = new BadMsType(pdb, 0);
|
||||
type.setRecordNumber(RecordNumber.make(recordCategory, recordNumber));
|
||||
return type;
|
||||
}
|
||||
if (recordNumber < typeIndexMin) {
|
||||
PrimitiveMsType primitive = primitiveTypesByRecordNumber.get(recordNumber);
|
||||
if (primitive == null) {
|
||||
primitive = new PrimitiveMsType(pdb, recordNumber);
|
||||
primitiveTypesByRecordNumber.put(recordNumber, primitive);
|
||||
}
|
||||
return primitive;
|
||||
}
|
||||
|
||||
RecordNumber rn = RecordNumber.make(recordCategory, recordNumber);
|
||||
OffLen offLen = offLenRecords.get(recordNumber - typeIndexMin);
|
||||
|
||||
try {
|
||||
PdbByteReader recordReader =
|
||||
pdb.getReaderForStreamNumber(streamNumber, offLen.offset(), offLen.length());
|
||||
return TypeParser.parseRecord(pdb, recordReader, rn);
|
||||
}
|
||||
catch (PdbException | IOException | CancelledException e) {
|
||||
BadMsType badType = new BadMsType(pdb, 0);
|
||||
badType.setRecordNumber(RecordNumber.make(recordCategory, recordNumber));
|
||||
return badType;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// Package-Protected Internals
|
||||
//==============================================================================================
|
||||
@ -165,7 +202,9 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
// Commented out, but this is currently where we might put this method. See the note
|
||||
// placed within the method (deserializeHashStreams()) for more information about why
|
||||
// we have this commented out.
|
||||
//hash.deserializeHashStreams(monitor);
|
||||
//hash.deserializeHashStreams(pdb.getMonitor());
|
||||
|
||||
createOffLenRecords(reader);
|
||||
|
||||
deserializeTypeRecords(reader);
|
||||
|
||||
@ -254,6 +293,20 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
//==============================================================================================
|
||||
// Internal Data Methods
|
||||
//==============================================================================================
|
||||
private void createOffLenRecords(PdbByteReader reader) throws PdbException, CancelledException {
|
||||
int savedIndex = reader.getIndex();
|
||||
offLenRecords = new ArrayList<>();
|
||||
while (reader.hasMore()) {
|
||||
pdb.checkCancelled();
|
||||
int recordLength = reader.parseUnsignedShortVal();
|
||||
// reading offset after parsing length so we have correct offset to read from later
|
||||
int offset = reader.getIndex();
|
||||
reader.skip(recordLength);
|
||||
offLenRecords.add(new OffLen(offset, recordLength));
|
||||
}
|
||||
reader.setIndex(savedIndex); // restore reader to original state
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the Type Records of this class
|
||||
* @param reader {@link PdbByteReader} from which to deserialize the data
|
||||
@ -418,8 +471,7 @@ public abstract class TypeProgramInterface implements TPI {
|
||||
if (hashStreamNumberAuxiliary == 0xffff) {
|
||||
return;
|
||||
}
|
||||
PdbByteReader readerAuxiliary =
|
||||
pdb.getReaderForStreamNumber(hashStreamNumberAuxiliary);
|
||||
PdbByteReader readerAuxiliary = pdb.getReaderForStreamNumber(hashStreamNumberAuxiliary);
|
||||
//readerAuxiliary.dump();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user