GP-0 fix test broken by GP-2367

This commit is contained in:
ghizard 2022-09-12 10:58:40 -04:00
parent 75a87036e6
commit bf114ef163
9 changed files with 555 additions and 155 deletions

View file

@ -0,0 +1,337 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
import ghidra.util.task.TaskMonitor;
/**
* This class represents the the Multi-Stream Format File used for Windows PDB files.
* We have intended to implement to the Microsoft PDB API (source); see the API for truth.
* <P>
* Derived classes represents the real formats. The file format represents a kind of
* file system within a file and is based upon pages in order to try to optimize
* disk I/O and system update. There was also a mechanism to allow for ping-ponged
* commit for file updates. Our implementation is only used for reading the file
* format; it is not intended to write or modify an existing file. Much work would
* need to be done to create a version with those capabilities.
* <P>
* The file format consists of a first page that contains identifying header information
* that consists of an ID string, and limited parameters needed for pointing to
* directory information and the Free Page Map. We do not use the latter information.
* <P>
* Note that the API (source) description on indicates that the original tools could
* have been built with different parameter sets, which also impacts the page size
* and other parameters for the format. We intended to create a reader that is capable
* of reading any of these files.
* <P>
* The file header generally contains the following information, but their sizes on disk
* depends on whether this is a file of the older or newer format. Generally, the fields follow:
* <PRE>
* Field Description Size on Disk Old Size on Disk New Java Type
* ID ID "string" 42 29 byte[]
* identifying
* old vs. new
* ID padding Padding between 2 3 N/A
* ID and next
* field
* Page Size Power-of-2 page 4 4 int
* size used
* Free Page Map Page Number of 2 4 int
* current free
* page map
* Number of Pages Number of pages 2 4 int
* currently used
* in the file
* Serialized Sequence of page
* info about numbers
* directory
* stream:
* -Directory Num of bytes 4+4 4 int
* Length + (opt addr field)
* -Page number Page number that 2+2 4
* contains page
* numbers for the
* stream; see note
* below regarding new!
* </PRE>
* The file directory is stored in stream 0, which has its information persisted in
* the header as described above. However, for the newest format, the page (pointed
* to in the header) for the directory stream has an extra level of indirection. The
* page contains page numbers, whose pages contain contain page numbers for the
* directory stream. Note that the page numbers listed on any of these pages have
* the following format on disk:
* <PRE>
* Field Description Size on Disk Old Size on Disk New Java Type
* Page Number Page Number 2+2 4 int
* + (opt addr field)
* </PRE>
* The directory stream contain StreamTable information, which is serialized into the
* directory stream as follows:
* <PRE>
* numStreams
* streamLength[numStreams]
* serializedStream[numStreams]
* </PRE>
* Note that the StreamTable parsed from the directory stream does not have the most
* up-to-date information about stream 0 (the directory stream); the up-to-date
* version of stream 0 is what was persisted in the header. So after the StreamTable
* has been deserialized from the directory stream, the stream 0 information in the
* StreamTable gets overwritten with the stream 0 that we had already obtained.
* <P>
* @see MsfFileReader
* @see MsfStream
* @see MsfDirectoryStream
* @see MsfFreePageMap
* @see MsfStreamTable
*/
public abstract class AbstractMsf implements Msf {
private static final int HEADER_PAGE_NUMBER = 0;
private static final int DIRECTORY_STREAM_NUMBER = 0;
//==============================================================================================
// Internals
//==============================================================================================
protected String filename;
protected MsfFileReader fileReader;
protected MsfFreePageMap freePageMap;
protected MsfDirectoryStream directoryStream;
protected MsfStreamTable streamTable;
protected int pageSize;
protected int log2PageSize;
protected int freePageMapNumSequentialPage;
protected int pageSizeModMask;
protected int currentFreePageMapFirstPageNumber;
protected int numPages = 1; // Set to 1 to allow initial read
protected TaskMonitor monitor;
protected PdbReaderOptions pdbOptions;
//==============================================================================================
// API
//==============================================================================================
/**
* 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, 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.
pageSize = 0x1000;
configureParameters();
// Create components.
fileReader = new MsfFileReader(this, file);
create();
}
/**
* Returns the filename
* @return the filename
*/
@Override
public String getFilename() {
return filename;
}
/**
* Returns the TaskMonitor
* @return the monitor
*/
@Override
public TaskMonitor getMonitor() {
return monitor;
}
/**
* Check to see if this monitor has been canceled
* @throws CancelledException if monitor has been cancelled
*/
@Override
public void checkCanceled() throws CancelledException {
monitor.checkCanceled();
}
/**
* Returns the page size employed by this {@link Msf}
* @return page size
*/
@Override
public int getPageSize() {
return pageSize;
}
/**
* Returns the number of streams found in this {@link Msf}
* @return number of streams
*/
@Override
public int getNumStreams() {
return streamTable.getNumStreams();
}
/**
* 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
*/
@Override
public MsfStream getStream(int streamNumber) {
return streamTable.getStream(streamNumber);
}
/**
* Returns the file reader
* @return the file reader
*/
public MsfFileReader getFileReader() {
return fileReader;
}
/**
* Closes resources used by this {@link Msf}
* @throws IOException under circumstances found when closing a {@link RandomAccessFile}
*/
@Override
public void close() throws IOException {
if (fileReader != null) {
fileReader.close();
}
}
//==============================================================================================
// 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
*/
@Override
public int getLog2PageSize() {
return log2PageSize;
}
/**
* 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
*/
@Override
public int getPageSizeModMask() {
return pageSizeModMask;
}
/**
* 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}
*/
@Override
public int getNumSequentialFreePageMapPages() {
return freePageMapNumSequentialPage;
}
/**
* Returns the page number containing the header of this MSF file
* @return the header page number
*/
@Override
public int getHeaderPageNumber() {
return HEADER_PAGE_NUMBER;
}
/**
* Returns the stream number containing the directory of this MSF file
* @return the directory stream number
*/
@Override
public int getDirectoryStreamNumber() {
return DIRECTORY_STREAM_NUMBER;
}
//==============================================================================================
// Internal Data Methods
//==============================================================================================
/**
* Returns the number of pages contained in this MSF file
* @return the number of pages in this MSF
*/
@Override
public 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
*/
@Override
public int getCurrentFreePageMapFirstPageNumber() {
return currentFreePageMapFirstPageNumber;
}
/**
* 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
* @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
*/
@Override
public void deserialize()
throws IOException, PdbException, CancelledException {
byte[] bytes = new byte[getPageSize()];
fileReader.read(getHeaderPageNumber(), 0, getPageSize(), bytes, 0);
PdbByteReader reader = new PdbByteReader(bytes);
reader.setIndex(getPageSizeOffset());
pageSize = reader.parseInt();
parseFreePageMapPageNumber(reader);
parseCurrentNumPages(reader);
configureParameters();
directoryStream.deserializeStreamInfo(reader);
// Do not need FreePageMap for just reading files.
freePageMap.deserialize();
// For debug: freePageMap.dump();
streamTable.deserialize(directoryStream);
}
}

View file

@ -17,9 +17,9 @@ 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.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;
@ -103,99 +103,50 @@ import ghidra.util.task.TaskMonitor;
* @see MsfFreePageMap
* @see MsfStreamTable
*/
public abstract class Msf implements AutoCloseable {
private static final int HEADER_PAGE_NUMBER = 0;
private static final int DIRECTORY_STREAM_NUMBER = 0;
//==============================================================================================
// Internals
//==============================================================================================
protected String filename;
protected MsfFileReader fileReader;
protected MsfFreePageMap freePageMap;
protected MsfDirectoryStream directoryStream;
protected MsfStreamTable streamTable;
protected int pageSize;
protected int log2PageSize;
protected int freePageMapNumSequentialPage;
protected int pageSizeModMask;
protected int currentFreePageMapFirstPageNumber;
protected int numPages = 1; // Set to 1 to allow initial read
protected TaskMonitor monitor;
protected PdbReaderOptions pdbOptions;
//==============================================================================================
// API
//==============================================================================================
/**
* 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 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.
pageSize = 0x1000;
configureParameters();
// Create components.
fileReader = new MsfFileReader(this, file);
create();
}
public interface Msf extends AutoCloseable {
/**
* Returns the filename
* @return the filename
*/
public String getFilename() {
return filename;
}
public String getFilename();
/**
* Returns the TaskMonitor
* @return the monitor
*/
public TaskMonitor getMonitor() {
return monitor;
}
public TaskMonitor getMonitor();
/**
* Check to see if this monitor has been canceled
* @throws CancelledException if monitor has been cancelled
*/
public void checkCanceled() throws CancelledException {
monitor.checkCanceled();
}
public void checkCanceled() throws CancelledException;
/**
* Returns the page size employed by this {@link Msf}
* @return page size
*/
public int getPageSize() {
return pageSize;
}
public int getPageSize();
/**
* Returns the number of streams found in this {@link Msf}
* @return number of streams
*/
public int getNumStreams() {
return streamTable.getNumStreams();
}
public int getNumStreams();
/**
* Returns the file reader
* @return the file reader
*/
public MsfFileReader getFileReader();
/**
* Closes resources used by this {@link Msf}
* @throws IOException under circumstances found when closing a {@link RandomAccessFile}
*/
@Override
public void close() throws IOException;
/**
* Returns the {@link MsfStream} specified by {@link Msf}
@ -203,20 +154,7 @@ public abstract class Msf implements AutoCloseable {
* 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 Msf}
* @throws IOException under circumstances found when closing a {@link RandomAccessFile}
*/
@Override
public void close() throws IOException {
if (fileReader != null) {
fileReader.close();
}
}
public MsfStream getStream(int streamNumber);
//==============================================================================================
// Package-Protected Utilities
@ -228,7 +166,7 @@ public abstract class Msf implements AutoCloseable {
* @param log2Divisor the log2 of the intended divisor value
* @return the floor of the division result
*/
static final int floorDivisionWithLog2Divisor(int dividend, int log2Divisor) {
static int floorDivisionWithLog2Divisor(int dividend, int log2Divisor) {
return (dividend + (1 << log2Divisor) - 1) >> log2Divisor;
}
@ -239,27 +177,27 @@ public abstract class Msf implements AutoCloseable {
* Method that returns the identification byte[] required by this format
* @return the minimum required number
*/
protected abstract byte[] getIdentification();
abstract byte[] getIdentification();
/**
* Returns the offset (in bytes) of the PageSize within the header
* @return the offset of the PageSize within the header
*/
protected abstract int getPageSizeOffset();
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
*/
protected abstract void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException;
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
*/
protected abstract void parseCurrentNumPages(PdbByteReader reader) throws PdbException;
abstract void parseCurrentNumPages(PdbByteReader reader) throws PdbException;
/**
* Method to create the following components: StreamTable, FreePageMap, and DirectoryStream.
@ -276,7 +214,7 @@ public abstract class Msf implements AutoCloseable {
* 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();
abstract int getPageNumberSize();
//==============================================================================================
// Class Internals
@ -285,43 +223,33 @@ public abstract class Msf implements AutoCloseable {
* 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;
}
int getLog2PageSize();
/**
* 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
*/
protected int getPageSizeModMask() {
return pageSizeModMask;
}
int getPageSizeModMask();
/**
* 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;
}
int getNumSequentialFreePageMapPages();
/**
* Returns the page number containing the header of this MSF file
* @return the header page number
*/
protected int getHeaderPageNumber() {
return HEADER_PAGE_NUMBER;
}
int getHeaderPageNumber();
/**
* Returns the stream number containing the directory of this MSF file
* @return the directory stream number
*/
protected int getDirectoryStreamNumber() {
return DIRECTORY_STREAM_NUMBER;
}
int getDirectoryStreamNumber();
//==============================================================================================
// Internal Data Methods
@ -330,17 +258,13 @@ public abstract class Msf implements AutoCloseable {
* Returns the number of pages contained in this MSF file
* @return the number of pages in this MSF
*/
protected int getNumPages() {
return numPages;
}
int getNumPages();
/**
* 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;
}
int getCurrentFreePageMapFirstPageNumber();
/**
* Performs required initialization of this class, needed before trying to read any
@ -351,25 +275,6 @@ public abstract class Msf implements AutoCloseable {
* @throws PdbException upon unknown value for configuration
* @throws CancelledException upon user cancellation
*/
protected void deserialize()
throws IOException, PdbException, CancelledException {
byte[] bytes = new byte[getPageSize()];
fileReader.read(getHeaderPageNumber(), 0, getPageSize(), bytes, 0);
PdbByteReader reader = new PdbByteReader(bytes);
reader.setIndex(getPageSizeOffset());
pageSize = reader.parseInt();
parseFreePageMapPageNumber(reader);
parseCurrentNumPages(reader);
configureParameters();
directoryStream.deserializeStreamInfo(reader);
// Do not need FreePageMap for just reading files.
freePageMap.deserialize();
// For debug: freePageMap.dump();
streamTable.deserialize(directoryStream);
}
void deserialize() throws IOException, PdbException, CancelledException;
}

View file

@ -25,7 +25,7 @@ import ghidra.util.task.TaskMonitor;
/**
* This class is the version of {@link Msf} for Microsoft v2.00 MSF.
*/
public class Msf200 extends Msf {
public class Msf200 extends AbstractMsf {
private static final int PAGE_NUMBER_SIZE = 2;
private static final byte[] IDENTIFICATION =
@ -74,14 +74,14 @@ public class Msf200 extends Msf {
// Abstract Methods
//==============================================================================================
@Override
void create() {
public void create() {
streamTable = new MsfStreamTable200(this);
freePageMap = new MsfFreePageMap200(this);
directoryStream = new MsfDirectoryStream200(this);
}
@Override
void configureParameters() throws PdbException {
public void configureParameters() throws PdbException {
switch (pageSize) {
case 0x400:
log2PageSize = 10;
@ -105,27 +105,27 @@ public class Msf200 extends Msf {
// Class Internals
//==============================================================================================
@Override
protected void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException {
public void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException {
currentFreePageMapFirstPageNumber = reader.parseShort();
}
@Override
protected void parseCurrentNumPages(PdbByteReader reader) throws PdbException {
public void parseCurrentNumPages(PdbByteReader reader) throws PdbException {
numPages = reader.parseShort();
}
@Override
protected int getPageNumberSize() {
public int getPageNumberSize() {
return PAGE_NUMBER_SIZE;
}
@Override
protected byte[] getIdentification() {
public byte[] getIdentification() {
return IDENTIFICATION;
}
@Override
protected int getPageSizeOffset() {
public int getPageSizeOffset() {
return PAGE_SIZE_OFFSET;
}

View file

@ -25,7 +25,7 @@ import ghidra.util.task.TaskMonitor;
/**
* This class is the version of {@link Msf} for Microsoft v7.00 MSF.
*/
public class Msf700 extends Msf {
public class Msf700 extends AbstractMsf {
private static final int PAGE_NUMBER_SIZE = 4;
private static final byte[] IDENTIFICATION = "Microsoft C/C++ MSF 7.00\r\n\u001aDS".getBytes();
@ -57,24 +57,24 @@ public class Msf700 extends Msf {
// Abstract Methods
//==============================================================================================
@Override
void create() {
public void create() {
streamTable = new MsfStreamTable700(this);
freePageMap = new MsfFreePageMap700(this);
directoryStream = new MsfDirectoryStream700(this);
}
@Override
protected void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException {
public void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException {
currentFreePageMapFirstPageNumber = reader.parseInt();
}
@Override
protected void parseCurrentNumPages(PdbByteReader reader) throws PdbException {
public void parseCurrentNumPages(PdbByteReader reader) throws PdbException {
numPages = reader.parseInt();
}
@Override
void configureParameters() throws PdbException {
public void configureParameters() throws PdbException {
switch (pageSize) {
case 0x200:
log2PageSize = 9;
@ -118,12 +118,12 @@ public class Msf700 extends Msf {
// Class Internals
//==============================================================================================
@Override
protected int getPageNumberSize() {
public int getPageNumberSize() {
return PAGE_NUMBER_SIZE;
}
@Override
protected byte[] getIdentification() {
public byte[] getIdentification() {
return IDENTIFICATION;
}

View file

@ -44,7 +44,7 @@ class MsfFreePageMap200 extends MsfFreePageMap {
void deserialize() throws IOException, CancelledException {
int size = msf.getNumSequentialFreePageMapPages() * msf.getPageSize();
byte[] bytes = new byte[size];
MsfFileReader fileReader = msf.fileReader;
MsfFileReader fileReader = msf.getFileReader();
fileReader.read(msf.getCurrentFreePageMapFirstPageNumber(), 0, size, bytes, 0);
addMap(bytes);
}

View file

@ -51,7 +51,7 @@ class MsfFreePageMap700 extends MsfFreePageMap {
int nextPageNumber = msf.getCurrentFreePageMapFirstPageNumber();
// Read the FreePageMap, which is dispersed across the file (see note below).
MsfFileReader fileReader = msf.fileReader;
MsfFileReader fileReader = msf.getFileReader();
int pageSize = msf.getPageSize();
while (freePageMapNumPages > 0) {
msf.checkCanceled();

View file

@ -112,8 +112,9 @@ public class MsfStream {
// Read any partial page at beginning first.
if (offsetIntoPage != 0) {
int firstNumToRead = Math.min(msf.getPageSize() - offsetIntoPage, remainingByteCount);
msf.fileReader.read(pageList.get(pageNumber), offsetIntoPage, firstNumToRead, bytes,
bytesOffset);
msf.getFileReader()
.read(pageList.get(pageNumber), offsetIntoPage, firstNumToRead, bytes,
bytesOffset);
if ((remainingByteCount - firstNumToRead) > remainingByteCount) {
throw new IOException("Integer count underflow when preparing to read.");
}
@ -138,8 +139,9 @@ public class MsfStream {
remainingByteCount -= numToReadInPage;
}
while (remainingByteCount > 0 && pageList.get(pageNumber) == lastSequentialPageNumber);
msf.fileReader.read(firstSequentialPageNumber, 0, numToReadInSequentialPages, bytes,
bytesOffset);
msf.getFileReader()
.read(firstSequentialPageNumber, 0, numToReadInSequentialPages, bytes,
bytesOffset);
bytesOffset += numToReadInSequentialPages;
}
}

View file

@ -17,6 +17,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
import java.io.IOException;
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.StubMsf;
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
/**
@ -41,9 +42,9 @@ public class DummyPdb700 extends Pdb700 {
* @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 {
super(null, new PdbReaderOptions());
public DummyPdb700(int tpiIndexMin, int tpiIndexMaxExclusive,
int ipiIndexMin, int ipiIndexMaxExclusive) throws IOException, PdbException {
super(new StubMsf(), new PdbReaderOptions());
typeProgramInterface =
new DummyTypeProgramInterface800(this, tpiIndexMin, tpiIndexMaxExclusive);
debugInfo = new DummyDebugInfoNew(this);

View file

@ -0,0 +1,155 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.pdb2.pdbreader.msf;
import java.io.IOException;
import javax.help.UnsupportedOperationException;
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* This class is an extension of {@link Pdb700}, based on {@link AbstractPdb}, whose sole purpose
* is to allow for testing of internal components of {@link AbstractPdb} classes. It is not
* part of the production PDB Reader.
*/
public class StubMsf implements Msf {
/**
* 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 MSF used for testing
*/
public StubMsf() {
}
@Override
public void close() throws IOException {
// Do nothing
}
@Override
public String getFilename() {
throw new UnsupportedOperationException();
}
@Override
public TaskMonitor getMonitor() {
return TaskMonitor.DUMMY;
}
@Override
public void checkCanceled() throws CancelledException {
TaskMonitor.DUMMY.checkCanceled();
}
@Override
public int getPageSize() {
throw new UnsupportedOperationException();
}
@Override
public int getNumStreams() {
throw new UnsupportedOperationException();
}
@Override
public MsfStream getStream(int streamNumber) {
throw new UnsupportedOperationException();
}
@Override
public MsfFileReader getFileReader() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getIdentification() {
throw new UnsupportedOperationException();
}
@Override
public int getPageSizeOffset() {
throw new UnsupportedOperationException();
}
@Override
public void parseFreePageMapPageNumber(PdbByteReader reader) throws PdbException {
throw new UnsupportedOperationException();
}
@Override
public void parseCurrentNumPages(PdbByteReader reader) throws PdbException {
throw new UnsupportedOperationException();
}
@Override
public void create() {
throw new UnsupportedOperationException();
}
@Override
public void configureParameters() throws PdbException {
throw new UnsupportedOperationException();
}
@Override
public int getPageNumberSize() {
throw new UnsupportedOperationException();
}
@Override
public int getLog2PageSize() {
throw new UnsupportedOperationException();
}
@Override
public int getPageSizeModMask() {
throw new UnsupportedOperationException();
}
@Override
public int getNumSequentialFreePageMapPages() {
throw new UnsupportedOperationException();
}
@Override
public int getHeaderPageNumber() {
throw new UnsupportedOperationException();
}
@Override
public int getDirectoryStreamNumber() {
throw new UnsupportedOperationException();
}
@Override
public int getNumPages() {
throw new UnsupportedOperationException();
}
@Override
public int getCurrentFreePageMapFirstPageNumber() {
throw new UnsupportedOperationException();
}
@Override
public void deserialize() throws IOException, PdbException, CancelledException {
throw new UnsupportedOperationException();
}
}