GP-4736 - PDB Refactor C11 and C13 Sections and Lines information and

create member access
This commit is contained in:
ghizard 2024-06-27 10:38:40 +00:00
parent d5cbda1e21
commit 99e087569f
36 changed files with 1595 additions and 1118 deletions

View File

@ -1,294 +0,0 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* C13Lines information. As best as we know, only one of C11Lines or C13Lines (We are actually
* creating a C13Debug class at a higher level, and making C13Lines be the specific C13Debug
* information for "type" 0xf2 (and maybe 0xf4) can be found after the symbol information in
* module debug streams.
*/
public class AbstractC13Lines extends C13Section {
private long offCon; // uint32
private int segCon; // uint16
private int flags; // uint16
private long lenCon; // uint32
private List<FileRecord> fileRecords = new ArrayList<>();
protected AbstractC13Lines(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(ignore);
if (reader.numRemaining() < 12) {
throw new PdbException("Not enough data for header");
}
offCon = reader.parseUnsignedIntVal();
segCon = reader.parseUnsignedShortVal();
flags = reader.parseUnsignedShortVal();
lenCon = reader.parseUnsignedIntVal();
boolean hasColumn = ((flags & 0X0001) != 0);
while (reader.hasMore()) {
monitor.checkCancelled();
FileRecord fileRecord = FileRecord.parse(reader, hasColumn, monitor);
if (fileRecord == null) {
break;
}
fileRecords.add(fileRecord);
}
}
long getOffCon() {
return offCon;
}
int getSegCon() {
return segCon;
}
int getFlags() {
return flags;
}
long getLenCon() {
return lenCon;
}
@Override
public String toString() {
return String.format(
"%s: offCon = %ld, segCon = %d, flags = 0x%04x, lenCon = %d; num records = %d",
getClass().getSimpleName(), offCon, segCon, flags, lenCon, fileRecords.size());
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13Lines----------------------------------------------------\n");
dumpInternal(writer, monitor);
writer.write("End C13Lines------------------------------------------------\n");
}
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
writer.write(String.format("offCon: 0x%08x segCon: %d flags: 0x%08x lenCon: 0x%08x\n",
offCon, segCon, flags, lenCon));
for (FileRecord record : fileRecords) {
monitor.checkCancelled();
record.dump(writer, offCon);
}
}
static class FileRecord {
private long fileId; // uint32
private long nLines; // uint32
private long lenFileBlock; // uint32
private List<LineRecord> lineRecords = new ArrayList<>();
static FileRecord parse(PdbByteReader reader, boolean hasColumn, TaskMonitor monitor)
throws PdbException {
return new FileRecord(reader, hasColumn, monitor);
}
private FileRecord(PdbByteReader reader, boolean hasColumn, TaskMonitor monitor)
throws PdbException {
if (reader.numRemaining() < 12) {
throw new PdbException("Not enough data for FileRecord header");
}
fileId = reader.parseUnsignedIntVal();
nLines = reader.parseUnsignedIntVal();
lenFileBlock = reader.parseUnsignedIntVal();
long lenMinusHeader = lenFileBlock - 12; // 12 is size of header
Long x = nLines;
int nLinesI = x.intValue();
int sizeLines = nLinesI * 8;
int sizeColumns = nLinesI * (hasColumn ? 4 : 0);
int sizeRequired = sizeLines + sizeColumns;
// was test ">" but both are suspect... not all records might have the columns
if (lenMinusHeader != sizeRequired) {
throw new PdbException("Corrupt FileRecord");
}
if (reader.numRemaining() < sizeRequired) {
throw new PdbException("Not enough data for FileRecord records");
}
PdbByteReader lineReader = reader.getSubPdbByteReader(sizeLines);
PdbByteReader columnReader =
(hasColumn ? reader.getSubPdbByteReader(sizeColumns) : null);
for (int i = 0; i < nLines; i++) {
LineRecord lineRecord = LineRecord.parse(lineReader, columnReader);
lineRecords.add(lineRecord);
}
}
long getFileId() {
return fileId;
}
long getNLines() {
return nLines;
}
long getLenFileBlock() {
return lenFileBlock;
}
List<LineRecord> getLineRecords() {
return lineRecords;
}
void dump(Writer writer, long offCon) throws IOException {
writer.write(String.format("fileId: %06x, nLines: %d, lenFileBlock: %d\n", getFileId(),
getNLines(), getLenFileBlock()));
for (int i = 0; i < getNLines(); i++) {
List<LineRecord> records = getLineRecords();
records.get(i).dump(writer, offCon);
writer.write("\n");
}
}
}
static class LineRecord {
private long offset; // uint32
private long bitVals; // uint32
private ColumnRecord columnRecord = null;
long getOffset() {
return offset;
}
long getBitVals() {
return bitVals;
}
long getLineNumStart() {
return bitVals & 0xffffffL;
}
long getDeltaLineEnd() {
return (bitVals >> 24) & 0x7fL;
}
ColumnRecord getColumnRecord() {
return columnRecord;
}
/**
* Returns true if the line number is that of an statement
* @return true if for an statement
*/
boolean isStatement() {
return (bitVals & 0x80000000L) != 0L;
}
/**
* Returns true if the line number is that of an expression
* @return true if for an expression
*/
boolean isExpression() {
return !isStatement();
}
static LineRecord parse(PdbByteReader lineReader, PdbByteReader columnReader)
throws PdbException {
return new LineRecord(lineReader, columnReader);
}
private LineRecord(PdbByteReader lineReader, PdbByteReader columnReader)
throws PdbException {
offset = lineReader.parseUnsignedIntVal();
bitVals = lineReader.parseUnsignedIntVal();
if (columnReader != null) { // means hasColumn is true
columnRecord = ColumnRecord.parse(columnReader);
}
}
private boolean isSpecialLine() {
long start = getLineNumStart();
return (start == 0xfeefeeL || start == 0xf00f00L);
}
void dump(Writer writer, long offCon) throws IOException {
String lineStart = (isSpecialLine() ? String.format("%06x", getLineNumStart())
: String.format("%d", getLineNumStart()));
if (columnRecord != null) {
if (columnRecord.getOffsetColumnEnd() != 0L) {
writer.write(String.format("%5d:%5d-%5d-%5d 0x%08x %s", getLineNumStart(),
columnRecord.getOffsetColumnStart(), getLineNumStart() + getDeltaLineEnd(),
columnRecord.getOffsetColumnEnd(), getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
else {
writer.write(String.format("%s-%5d 0x%08x %s", lineStart,
columnRecord.getOffsetColumnStart(), getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
}
else {
writer.write(String.format("%s 0x%08x %s", lineStart, getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
}
}
static class ColumnRecord {
private int offsetColumnStart; // unsigned short
private int offsetColumnEnd; // unsigned short
int getOffsetColumnStart() {
return offsetColumnStart;
}
int getOffsetColumnEnd() {
return offsetColumnEnd;
}
static ColumnRecord parse(PdbByteReader reader) throws PdbException {
return new ColumnRecord(reader);
}
private ColumnRecord(PdbByteReader reader) throws PdbException {
offsetColumnStart = reader.parseUnsignedShortVal();
offsetColumnEnd = reader.parseUnsignedShortVal();
}
@Override
public String toString() {
return String.format("Start: 0x%04x, End: 0x%04x", getOffsetColumnStart(),
getOffsetColumnEnd());
}
}
}

View File

@ -0,0 +1,127 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* C13Lines information. As best as we know, only one of C11Lines or C13Lines (We are actually
* creating a C13Debug class at a higher level, and making C13Lines be the specific C13Debug
* information for "type" 0xf2 (and maybe 0xf4) can be found after the symbol information in
* module debug streams.
*/
public class AbstractLinesC13Section extends C13Section {
private long offCon; // uint32
private int segCon; // uint16
private int flags; // uint16
private long lenCon; // uint32
private List<C13FileRecord> fileRecords = new ArrayList<>();
protected AbstractLinesC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(ignore);
if (reader.numRemaining() < 12) {
throw new PdbException("Not enough data for header");
}
offCon = reader.parseUnsignedIntVal();
segCon = reader.parseUnsignedShortVal();
flags = reader.parseUnsignedShortVal();
lenCon = reader.parseUnsignedIntVal();
boolean hasColumn = ((flags & 0X0001) != 0);
while (reader.hasMore()) {
monitor.checkCancelled();
C13FileRecord fileRecord = C13FileRecord.parse(reader, hasColumn, monitor);
if (fileRecord == null) {
break;
}
fileRecords.add(fileRecord);
}
}
/**
* Returns the offCon value. Note that we are not certain, but think it is the offset
* within the particular memory segment for a chuck of records
* @return the offCon value
*/
public long getOffCon() {
return offCon;
}
/**
* Returns the segment value. We believe this is the segment that goes with the offCon
* value pertaining to a chunk of records
* @return the segment
*/
public int getSegCon() {
return segCon;
}
/**
* Flags for the chunk of records. We have not determined what any of the flag values
* represent
* @return the flags
*/
public int getFlags() {
return flags;
}
/**
* Returns the lenCon value. We are not certain, but believe this to be the length (bytes
* in memory) of the chunk of records
* @return the lenCon
*/
public long getLenCon() {
return lenCon;
}
/**
* Returns a list of file records for this chunk
* @return the file records
*/
public List<C13FileRecord> getFileRecords() {
return fileRecords;
}
@Override
public String toString() {
return String.format(
"%s: offCon = %ld, segCon = %d, flags = 0x%04x, lenCon = %d; num records = %d",
getClass().getSimpleName(), offCon, segCon, flags, lenCon, fileRecords.size());
}
@Override
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
writer.write(String.format("offCon: 0x%08x segCon: %d flags: 0x%08x lenCon: 0x%08x\n",
offCon, segCon, flags, lenCon));
for (C13FileRecord record : fileRecords) {
monitor.checkCancelled();
record.dump(writer, offCon);
}
}
}

View File

@ -18,6 +18,7 @@ package ghidra.app.util.bin.format.pdb2.pdbreader;
import java.io.IOException;
import java.io.Writer;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
@ -40,13 +41,11 @@ abstract class AbstractUnimplementedC13Section extends C13Section {
}
@Override
void dump(Writer writer, TaskMonitor monitor) throws IOException {
String n = getClass().getSimpleName();
int len = n.length();
writer.write(n + dashes.substring(len));
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
writer.write("***NOT IMPLEMENTED*** Bytes follow...\n");
writer.write(myReader.dump());
writer.write("\n");
writer.write("End " + n + dashes.substring(len + 4));
}
}

View File

@ -34,14 +34,14 @@ public class C11Lines {
// array of (Windows C) unsigned long values (which is 32-bit int); we are limiting to java int.
// The value is used to move the PdbByteReader index, which takes an int.
private List<Integer> baseSrcFile;
private List<StartEnd> startEnd;
private List<C11LinesStartEnd> startEnd;
private List<Integer> seg; // array of unsigned shorts
private List<Integer> ccSegs;
// array of (Windows C) unsigned long values (which is 32-bit int); we are limiting to java int.
// The value is used to move the PdbByteReader index, which takes an int.
private List<List<Integer>> baseSrcLines;
private List<List<StartEnd>> startEnds;
private List<List<C11LinesStartEnd>> startEnds;
private List<String> names;
private List<List<Integer>> segmentNumbers; // unsigned short
@ -53,6 +53,116 @@ public class C11Lines {
return new C11Lines(pdb, reader);
}
//==============================================================================================
// The below access methods might be temporary until it is decided if some work should
// be done within the class with methods to access the work.
/**
* Returns the number of source files
* @return the number of source files
*/
public int getNumFiles() {
return cFile;
}
/**
* Returns the number of segments. This also is the number of start/end records. This is
* a high-level list whereas there is a per-file list later. Not sure if this current list
* is an encompassing list or something else
* @return the number of segments
*/
public int getNumSegments() {
return cSeg;
}
/**
* Returns the list of segment numbers. This is a high-level list whereas there is a
* per-file list later. Not sure if this current list is an encompassing list or something
* else
* @return the segment numbers
*/
public List<Integer> getSegments() {
return seg;
}
/**
* Returns the list of line start/end records. This is a high-level list whereas there is
* a per-file list of start-end records at a lower level. Not sure if this current list is
* an encompassing list or a list of something else
* @return the list of start/end records
*/
public List<C11LinesStartEnd> getStartEnd() {
return startEnd;
}
/**
* Returns the list of base source file indices? This is our best guess at this time
* @return the indices of the source files
*/
public List<Integer> getBaseSrcFiles() {
return baseSrcFile;
}
/**
* Returns the list of the number of segments for each source file
* @return the list of the number of segments
*/
public List<Integer> getPerFileNumSegments() {
return ccSegs;
}
/**
* Returns the per-file list of base source lines, where the base is for the particular
* segment
* @return the per-file list of base source lines
*/
public List<List<Integer>> getPerFileBaseSrcLines() {
return baseSrcLines;
}
/**
* Returns the per-file list of line start/end records, where the start/ends are for the
* particular segment
* @return the per-file list of segment start/ends
*/
public List<List<C11LinesStartEnd>> getPerFileStartEndRecords() {
return startEnds;
}
/**
* The list of file names
* @return the list of file names
*/
public List<String> getFileNames() {
return names;
}
/**
* Returns the per-file list of segment numbers
* @return the per-file list of segment numbers
*/
public List<List<Integer>> getPerFileSegmentNumbers() {
return segmentNumbers;
}
/**
* Returns the per-file list of per-segment list of offsets
* @return the offsets
*/
public List<List<List<Long>>> getPerFilePerSegmentOffsets() {
return offsets;
}
/**
* Returns the per-file list of per-segment list of line numbers pertaining to the offsets
* @return the line numbers
*/
public List<List<List<Integer>>> getPerFilePerSegmentLineNumbers() {
return lineNumbers;
}
// The above access methods... see note above.
//==============================================================================================
private C11Lines(AbstractPdb pdb, PdbByteReader reader)
throws PdbException, CancelledException {
this.pdb = pdb;
@ -74,7 +184,7 @@ public class C11Lines {
}
for (int i = 0; i < cSeg; i++) {
pdb.checkCancelled();
StartEnd se = new StartEnd();
C11LinesStartEnd se = new C11LinesStartEnd();
se.parse(reader);
startEnd.add(se);
}
@ -101,9 +211,9 @@ public class C11Lines {
baseSrcLn.add(reader.parseInt());
}
baseSrcLines.add(baseSrcLn);
List<StartEnd> myStartEnd = new ArrayList<>();
List<C11LinesStartEnd> myStartEnd = new ArrayList<>();
for (int j = 0; j < ccSeg; j++) {
StartEnd se = new StartEnd();
C11LinesStartEnd se = new C11LinesStartEnd();
se.parse(reader);
myStartEnd.add(se);
}
@ -171,9 +281,9 @@ public class C11Lines {
builder.append(
" file[" + i + "]: cSeg: " + ccSegs.get(i) + " name: " + names.get(i) + "\n");
List<Integer> myBaseSrcLn = baseSrcLines.get(i);
List<StartEnd> myStartEnds = startEnds.get(i);
List<C11LinesStartEnd> myStartEnds = startEnds.get(i);
for (int j = 0; j < ccSegs.get(i); j++) {
StartEnd se = myStartEnds.get(j);
C11LinesStartEnd se = myStartEnds.get(j);
builder.append(" " + j + ": baseSrcLn: " + myBaseSrcLn.get(j) + " start: " +
se.getStart() + " end: " + se.getEnd() + "\n");
}
@ -195,22 +305,4 @@ public class C11Lines {
return builder.toString();
}
private class StartEnd {
private long start; // unsigned long
private long end; // unsigned long
public void parse(PdbByteReader reader) throws PdbException {
start = reader.parseUnsignedIntVal();
end = reader.parseUnsignedIntVal();
}
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
}
}

View File

@ -0,0 +1,45 @@
/* ###
* 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;
/**
* An individual PDB C11 Line Start/End record (think these are offsets in a segment)
*/
public class C11LinesStartEnd {
private long start; // unsigned long
private long end; // unsigned long
public void parse(PdbByteReader reader) throws PdbException {
start = reader.parseUnsignedIntVal();
end = reader.parseUnsignedIntVal();
}
/**
* Returns the start line value
* @return the start value
*/
public long getStart() {
return start;
}
/**
* Returns the end line value
* @return the end value
*/
public long getEnd() {
return end;
}
}

View File

@ -0,0 +1,54 @@
/* ###
* 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;
import java.util.HashMap;
import java.util.Map;
import ghidra.util.Msg;
/**
* The PDB C13 Checksum Type
*/
public enum C13ChecksumType {
UnknownChecksumType(-0x01),
NoneChecksumType(0x00),
Md5ChecksumType(0x01),
Sha1ChecksumType(0x02),
Sha256ChecksumType(0x03);
private static final Map<Integer, C13ChecksumType> BY_VALUE = new HashMap<>();
static {
for (C13ChecksumType val : values()) {
BY_VALUE.put(val.value, val);
}
}
private final int value;
public static C13ChecksumType fromValue(int val) {
C13ChecksumType t = BY_VALUE.getOrDefault(val, UnknownChecksumType);
if (t == UnknownChecksumType && val != UnknownChecksumType.value) {
Msg.warn(null,
String.format("PDB: C13FileChecksum - Unknown checksum type %08x", val));
}
return t;
}
private C13ChecksumType(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,55 @@
/* ###
* 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;
/**
* A PDB C13 Line Number Column Record
*/
public class C13ColumnRecord {
private int offsetColumnStart; // unsigned short
private int offsetColumnEnd; // unsigned short
/**
* Returns the column start for the offset
* @return the column start
*/
public int getOffsetColumnStart() {
return offsetColumnStart;
}
/**
* Returns the column end for the offset
* @return the column end
*/
public int getOffsetColumnEnd() {
return offsetColumnEnd;
}
static C13ColumnRecord parse(PdbByteReader reader) throws PdbException {
return new C13ColumnRecord(reader);
}
private C13ColumnRecord(PdbByteReader reader) throws PdbException {
offsetColumnStart = reader.parseUnsignedShortVal();
offsetColumnEnd = reader.parseUnsignedShortVal();
}
@Override
public String toString() {
return String.format("Start: 0x%04x, End: 0x%04x", getOffsetColumnStart(),
getOffsetColumnEnd());
}
}

View File

@ -0,0 +1,54 @@
/* ###
* 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;
/**
* An individual PDB C13 Cross-Scope Export record
*/
public class C13CrossScopeExport {
private long localId; // unsigned 32-bit
private long globalId; // unsigned 32-bit
public static int getBaseRecordSize() {
return 8;
}
public C13CrossScopeExport(PdbByteReader reader) throws PdbException {
localId = reader.parseUnsignedIntVal();
globalId = reader.parseUnsignedIntVal();
}
/**
* Returns the local ID
* @return the local ID
*/
public long getLocalId() {
return localId;
}
/**
* Returns the global ID
* @return the global ID
*/
public long getGlobalId() {
return globalId;
}
@Override
public String toString() {
return String.format("0x%08x, 0x%08x", localId, globalId);
}
}

View File

@ -0,0 +1,75 @@
/* ###
* 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;
import java.util.ArrayList;
import java.util.List;
/**
* An individual PDB C13 Cross-Scope Import record
*/
public class C13CrossScopeImport {
private int offsetObjectFilePath; // the module file; signed 32-bit
private long numCrossReferences; // unsigned 32-bit
private List<Long> referenceIds; // Array of unsigned 32-bit values
public static int getBaseRecordSize() {
return 8;
}
public C13CrossScopeImport(PdbByteReader reader) throws PdbException {
offsetObjectFilePath = reader.parseInt();
numCrossReferences = reader.parseUnsignedIntVal();
referenceIds = new ArrayList<>();
for (long i = 0; i < numCrossReferences; i++) {
referenceIds.add(reader.parseUnsignedIntVal());
}
}
/**
* Returns the offset to the module file pathname in the filename records
* @return the offset of the module file pathname
*/
public long getOffsetObjectFilePath() {
return offsetObjectFilePath;
}
/**
* Returns the number of cross references
* @return the number of cross references
*/
public long getNumCrossReferences() {
return numCrossReferences;
}
/**
* Returns the list of cross-references. Not sure exactly what these are at this time
* @return the cross-references
*/
public List<Long> getReferenceIds() {
return referenceIds;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%08x, %5d", offsetObjectFilePath, numCrossReferences));
for (Long id : referenceIds) {
builder.append(String.format(" 0x%08x", id));
}
return builder.toString();
}
}

View File

@ -1,130 +0,0 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13 Cross-Scope Imports information.... also known as Cross-Scope References.
*/
public class C13CrossScopeImports extends C13Section {
private List<CrossScopeImport> crossScopeImports = new ArrayList<>();
/**
* Parse and return a {@link C13CrossScopeImports}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static C13CrossScopeImports parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13CrossScopeImports(reader, ignore, monitor);
}
protected C13CrossScopeImports(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws CancelledException, PdbException {
super(ignore);
while (reader.numRemaining() >= CrossScopeImport.getBaseRecordSize()) {
monitor.checkCancelled();
CrossScopeImport crossImport = new CrossScopeImport(reader);
crossScopeImports.add(crossImport);
}
if (reader.hasMore()) {
Msg.debug(C13CrossScopeExports.class,
String.format("Num Extra C13CrossScopeExports bytes: %d", reader.numRemaining()));
}
}
List<CrossScopeImport> getCrossScopeImports() {
return crossScopeImports;
}
@Override
public String toString() {
return String.format("%s: num cross-scope imports = %d", getClass().getSimpleName(),
crossScopeImports.size());
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13CrossScopeImports----------------------------------------\n");
for (CrossScopeImport crossScopeImport : crossScopeImports) {
monitor.checkCancelled();
writer.write(crossScopeImport.toString());
writer.write('\n');
}
writer.write("End C13CrossScopeImports------------------------------------\n");
}
static class CrossScopeImport {
private int offsetObjectFilePath; // the module file; signed 32-bit
private long numCrossReferences; // unsigned 32-bit
private List<Long> referenceIds; // Array of unsigned 32-bit values
private static int getBaseRecordSize() {
return 8;
}
CrossScopeImport(PdbByteReader reader) throws PdbException {
offsetObjectFilePath = reader.parseInt();
numCrossReferences = reader.parseUnsignedIntVal();
referenceIds = new ArrayList<>();
for (long i = 0; i < numCrossReferences; i++) {
referenceIds.add(reader.parseUnsignedIntVal());
}
}
long getOffsetObjectFilePath() {
return offsetObjectFilePath;
}
long getNumCrossReferences() {
return numCrossReferences;
}
List<Long> getReferenceIds() {
return referenceIds;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%08x, %5d", offsetObjectFilePath, numCrossReferences));
for (Long id : referenceIds) {
builder.append(String.format(" 0x%08x", id));
}
return builder.toString();
}
}
}

View File

@ -0,0 +1,70 @@
/* ###
* 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;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* An extended version of the PDB C13 inlinee source line record that has extra file IDs
*/
public class C13ExtendedInlineeSourceLine extends C13InlineeSourceLine {
static int getBaseRecordSize() {
return 16;
}
private List<Integer> extraFileIds = new ArrayList<>(); // array of longs
C13ExtendedInlineeSourceLine(PdbByteReader reader, TaskMonitor monitor)
throws PdbException, CancelledException {
super(reader);
long numExtraFiles = reader.parseUnsignedIntVal(); // unsigned int
for (long i = 0; i < numExtraFiles; i++) {
monitor.checkCancelled();
extraFileIds.add(reader.parseInt());
}
}
/**
* Returns the number of extra file IDs
* @return the number
*/
public int getNumExtraFileIds() {
return extraFileIds.size();
}
/**
* Returns the list of extra file IDs
* @return the extra file IDs
*/
public List<Integer> getExtraFileIds() {
return extraFileIds;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%09x, 0x%06x, %d", inlinee, fileId, sourceLineNum));
for (Integer id : extraFileIds) {
builder.append(String.format(" 0x%06x", id));
}
return builder.toString();
}
}

View File

@ -0,0 +1,81 @@
/* ###
* 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;
import ghidra.util.NumericUtilities;
/**
* PDB C13 Module File Checksum for one file.
*/
public class C13FileChecksum {
private long offsetFilename; // unsigned 32-bit
private int length;
private int checksumTypeValue;
private byte[] bytes;
static int getBaseRecordSize() {
return 6;
}
C13FileChecksum(PdbByteReader reader) throws PdbException {
offsetFilename = reader.parseUnsignedIntVal();
length = reader.parseUnsignedByteVal();
checksumTypeValue = reader.parseUnsignedByteVal();
bytes = reader.parseBytes(length);
reader.align4();
}
/**
* Returns of offset of the filename within the filename list
* @return the offset of the filename
*/
public long getOffsetFilename() {
return offsetFilename;
}
/**
* Returns the number of bytes of the checksum field
* @return the number of bytes of the checksum field
*/
public long getLength() {
return length;
}
/**
* Returns the ID value of the checksum type use
* @return the ID of the checksum type
*/
public int getChecksumTypeValue() {
return checksumTypeValue;
}
/**
* Returns the checksum bytes
* @return the checksum bytes
*/
public byte[] getChecksumBytes() {
return bytes;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%08x, 0x%02x %s(%02x): ", offsetFilename, length,
C13ChecksumType.fromValue(checksumTypeValue), checksumTypeValue));
builder.append(NumericUtilities.convertBytesToString(bytes));
return builder.toString();
}
}

View File

@ -1,163 +0,0 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import ghidra.util.Msg;
import ghidra.util.NumericUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13 Module File Checksums.
*/
public class C13FileChecksums extends C13Section {
private List<FileChecksum> fileChecksums = new ArrayList<>();
/**
* Parse and return a {@link C13FileChecksums}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static C13FileChecksums parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13FileChecksums(reader, ignore, monitor);
}
protected C13FileChecksums(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws CancelledException, PdbException {
super(ignore);
while (reader.numRemaining() >= FileChecksum.getBaseRecordSize()) {
monitor.checkCancelled();
FileChecksum fileChecksum = new FileChecksum(reader);
fileChecksums.add(fileChecksum);
}
if (reader.hasMore()) {
Msg.debug(C13FileChecksums.class,
String.format("Num Extra C13FileChecksums bytes: %d", reader.numRemaining()));
}
}
public List<FileChecksum> getFileChecksums() {
return fileChecksums;
}
@Override
public String toString() {
return String.format("%s: num checksums = %d", getClass().getSimpleName(),
fileChecksums.size());
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13FileChecksums--------------------------------------------\n");
for (FileChecksum checksum : fileChecksums) {
monitor.checkCancelled();
writer.write(checksum.toString());
writer.write('\n');
}
writer.write("End C13FileChecksums----------------------------------------\n");
}
static class FileChecksum {
private long offsetFilename; // unsigned 32-bit
private int length;
private int checksumTypeValue;
private byte[] bytes;
private static int getBaseRecordSize() {
return 6;
}
FileChecksum(PdbByteReader reader) throws PdbException {
offsetFilename = reader.parseUnsignedIntVal();
length = reader.parseUnsignedByteVal();
checksumTypeValue = reader.parseUnsignedByteVal();
bytes = reader.parseBytes(length);
reader.align4();
}
long getOffsetFilename() {
return offsetFilename;
}
long getLength() {
return length;
}
long getChecksumTypeValue() {
return checksumTypeValue;
}
byte[] getChecsumBytes() {
return bytes;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%08x, 0x%02x %s(%02x): ", offsetFilename, length,
ChecksumType.fromValue(checksumTypeValue), checksumTypeValue));
builder.append(NumericUtilities.convertBytesToString(bytes));
return builder.toString();
}
}
private static enum ChecksumType {
UnknownChecksumType(-0x01),
NoneChecksumType(0x00),
Md5ChecksumType(0x01),
Sha1ChecksumType(0x02),
Sha256ChecksumType(0x03);
private static final Map<Integer, ChecksumType> BY_VALUE = new HashMap<>();
static {
for (ChecksumType val : values()) {
BY_VALUE.put(val.value, val);
}
}
private final int value;
public static ChecksumType fromValue(int val) {
ChecksumType t = BY_VALUE.getOrDefault(val, UnknownChecksumType);
if (t == UnknownChecksumType && val != UnknownChecksumType.value) {
Msg.warn(null,
String.format("PDB: C13FileChecksum - Unknown checksum type %08x", val));
}
return t;
}
private ChecksumType(int value) {
this.value = value;
}
}
}

View File

@ -0,0 +1,118 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.task.TaskMonitor;
/**
* A PDB C13 File Record pertaining to source line information
*/
public class C13FileRecord {
private long fileId; // uint32
private long nLines; // uint32
private long lenFileBlock; // uint32
private List<C13LineRecord> lineRecords = new ArrayList<>();
static C13FileRecord parse(PdbByteReader reader, boolean hasColumn, TaskMonitor monitor)
throws PdbException {
return new C13FileRecord(reader, hasColumn, monitor);
}
private C13FileRecord(PdbByteReader reader, boolean hasColumn, TaskMonitor monitor)
throws PdbException {
if (reader.numRemaining() < 12) {
throw new PdbException("Not enough data for FileRecord header");
}
fileId = reader.parseUnsignedIntVal();
nLines = reader.parseUnsignedIntVal();
lenFileBlock = reader.parseUnsignedIntVal();
long lenMinusHeader = lenFileBlock - 12; // 12 is size of header
Long x = nLines;
int nLinesI = x.intValue();
int sizeLines = nLinesI * 8;
int sizeColumns = nLinesI * (hasColumn ? 4 : 0);
int sizeRequired = sizeLines + sizeColumns;
// was test ">" but both are suspect... not all records might have the columns
if (lenMinusHeader != sizeRequired) {
throw new PdbException("Corrupt FileRecord");
}
if (reader.numRemaining() < sizeRequired) {
throw new PdbException("Not enough data for FileRecord records");
}
PdbByteReader lineReader = reader.getSubPdbByteReader(sizeLines);
PdbByteReader columnReader =
(hasColumn ? reader.getSubPdbByteReader(sizeColumns) : null);
for (int i = 0; i < nLines; i++) {
C13LineRecord lineRecord = C13LineRecord.parse(lineReader, columnReader);
lineRecords.add(lineRecord);
}
}
/**
* Returns the file ID
* @return the file ID
*/
public int getFileId() {
// We will need to watch for this to blow and then re-evaluate. I doubt that the list
// of names needs more than 2GB of characters
Long v = fileId;
return v.intValue();
//return fileId;
}
/**
* Returns the number of lines for the file record
* @return the number of lines
*/
public long getNLines() {
return nLines;
}
/**
* Returns the length of the block of records
* @return the length
*/
public long getLenFileBlock() {
return lenFileBlock;
}
/**
* Returns the list of line records for the file record
* @return the line records
*/
public List<C13LineRecord> getLineRecords() {
return lineRecords;
}
void dump(Writer writer, long offCon) throws IOException {
writer.write(String.format("fileId: %06x, nLines: %d, lenFileBlock: %d\n", getFileId(),
getNLines(), getLenFileBlock()));
for (int i = 0; i < getNLines(); i++) {
List<C13LineRecord> records = getLineRecords();
records.get(i).dump(writer, offCon);
writer.write("\n");
}
}
}

View File

@ -1,190 +0,0 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13InlineeLines information.
*/
public class C13InlineeLines extends C13Section {
// These are actually DWORDs, but we are ignoring the unsigned nature and using int.
private static final int InlineeSourceLineSignature = 0x0;
private static final int ExtendedInlineeSourceLineSignature = 0x1;
private int signature; //actually a DWORD (unsigned int)
private List<InlineeSourceLine> inlineeLines = new ArrayList<>();
/**
* Parse and return a {@link C13InlineeLines}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static C13InlineeLines parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13InlineeLines(reader, ignore, monitor);
}
private static List<InlineeSourceLine> parseInlineeLines(PdbByteReader reader,
TaskMonitor monitor) throws CancelledException, PdbException {
List<InlineeSourceLine> lines = new ArrayList<>();
while (reader.numRemaining() >= InlineeSourceLine.getBaseRecordSize()) {
monitor.checkCancelled();
InlineeSourceLine line = new InlineeSourceLine(reader);
lines.add(line);
}
return lines;
}
private static List<InlineeSourceLine> parseExtendedInlineeLines(PdbByteReader reader,
TaskMonitor monitor) throws CancelledException, PdbException {
List<InlineeSourceLine> lines = new ArrayList<>();
while (reader.numRemaining() >= ExtendedInlineeSourceLine.getBaseRecordSize()) {
monitor.checkCancelled();
ExtendedInlineeSourceLine line = new ExtendedInlineeSourceLine(reader, monitor);
lines.add(line);
}
return lines;
}
protected C13InlineeLines(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(ignore);
signature = reader.parseInt(); //actually a DWORD (unsigned int)
switch (signature) {
case InlineeSourceLineSignature:
inlineeLines = parseInlineeLines(reader, monitor);
break;
case ExtendedInlineeSourceLineSignature:
inlineeLines = parseExtendedInlineeLines(reader, monitor);
break;
default:
inlineeLines = new ArrayList<>();
break;
}
if (reader.hasMore()) {
Msg.debug(C13InlineeLines.class,
String.format("Extra inlinee bytes remain for signature: 0x%03x", signature));
}
}
List<InlineeSourceLine> getInlineeLines() {
return inlineeLines;
}
@Override
public String toString() {
return String.format("%s: num inlinee lines = %d", getClass().getSimpleName(),
inlineeLines.size());
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13InlineeLines---------------------------------------------\n");
writer.write(String.format("Signature: 0x%03x\n", signature));
for (InlineeSourceLine line : inlineeLines) {
monitor.checkCancelled();
writer.write(line.toString());
writer.write('\n');
}
writer.write("End C13InlineeLines-----------------------------------------\n");
}
static class InlineeSourceLine {
protected long inlinee; // unsigned 32-bit
protected int fileId;
protected int sourceLineNum;
private static int getBaseRecordSize() {
return 12;
}
InlineeSourceLine(PdbByteReader reader) throws PdbException {
inlinee = reader.parseUnsignedIntVal();
fileId = reader.parseInt();
sourceLineNum = reader.parseInt();
}
long getInlinee() {
return inlinee;
}
long getFileId() {
return fileId;
}
long getSourceLineNum() {
return sourceLineNum;
}
@Override
public String toString() {
return String.format("0x%09x, 0x%06x, %d", inlinee, fileId, sourceLineNum);
}
}
static class ExtendedInlineeSourceLine extends InlineeSourceLine {
private static int getBaseRecordSize() {
return 16;
}
private List<Integer> extraFileIds = new ArrayList<>(); // array of longs
ExtendedInlineeSourceLine(PdbByteReader reader, TaskMonitor monitor)
throws PdbException, CancelledException {
super(reader);
long numExtraFiles = reader.parseUnsignedIntVal(); // unsigned int
for (long i = 0; i < numExtraFiles; i++) {
monitor.checkCancelled();
extraFileIds.add(reader.parseInt());
}
}
int getNumExtraFileIds() {
return extraFileIds.size();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(String.format("0x%09x, 0x%06x, %d", inlinee, fileId, sourceLineNum));
for (Integer id : extraFileIds) {
builder.append(String.format(" 0x%06x", id));
}
return builder.toString();
}
}
}

View File

@ -0,0 +1,64 @@
/* ###
* 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;
/**
* A PDB C13 inlinee source line record
*/
public class C13InlineeSourceLine {
protected long inlinee; // unsigned 32-bit
protected int fileId;
protected int sourceLineNum;
static int getBaseRecordSize() {
return 12;
}
C13InlineeSourceLine(PdbByteReader reader) throws PdbException {
inlinee = reader.parseUnsignedIntVal();
fileId = reader.parseInt();
sourceLineNum = reader.parseInt();
}
/**
* Returns the inlinee value. Not sure how to interpret this value at this time
* @return the inlinee value
*/
public long getInlinee() {
return inlinee;
}
/**
* Returns the file ID
* @return the file ID
*/
public int getFileId() {
return fileId;
}
/**
* Returns the source line number
* @return the line number
*/
public long getSourceLineNum() {
return sourceLineNum;
}
@Override
public String toString() {
return String.format("0x%09x, 0x%06x, %d", inlinee, fileId, sourceLineNum);
}
}

View File

@ -0,0 +1,123 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
/**
* A PDB C13 Line Record that is part of a File Record
*/
public class C13LineRecord {
private long offset; // uint32
private long bitVals; // uint32
private C13ColumnRecord columnRecord = null;
/**
* Returns the offset within the segment for this line record
* @return the offset
*/
public long getOffset() {
return offset;
}
/**
* Returns the line number start for this record
* @return the line number start
*/
public long getLineNumStart() {
return bitVals & 0xffffffL;
}
/**
* Returns the delta between the line number start and the line number end (used to calculate
* the line number end)
* @return the delta between the line number start and the line number end
*/
public long getDeltaLineEnd() {
return (bitVals >> 24) & 0x7fL;
}
/**
* Returns the column record
* @return the column record or {@code null} if one does not exist
*/
public C13ColumnRecord getColumnRecord() {
return columnRecord;
}
/**
* Returns {@code true} if the line number is that of an statement; else is expression
* @return {@code true} if for an statement
*/
public boolean isStatement() {
return (bitVals & 0x80000000L) != 0L;
}
/**
* Returns {@code true} if the line number is that of an expression; else is statement
* @return {@code true} if for an expression
*/
public boolean isExpression() {
return !isStatement();
}
/**
* Returns {@code true} if is a special line (start is {@code 0xfeefee} or {@code 0xf00f00}).
* We do not know how to interpret either of these special line values at this time
* @return {@code true} if is a special line
*/
public boolean isSpecialLine() {
long start = getLineNumStart();
return (start == 0xfeefeeL || start == 0xf00f00L);
}
static C13LineRecord parse(PdbByteReader lineReader, PdbByteReader columnReader)
throws PdbException {
return new C13LineRecord(lineReader, columnReader);
}
private C13LineRecord(PdbByteReader lineReader, PdbByteReader columnReader)
throws PdbException {
offset = lineReader.parseUnsignedIntVal();
bitVals = lineReader.parseUnsignedIntVal();
if (columnReader != null) { // means hasColumn is true
columnRecord = C13ColumnRecord.parse(columnReader);
}
}
void dump(Writer writer, long offCon) throws IOException {
String lineStart = (isSpecialLine() ? String.format("%06x", getLineNumStart())
: String.format("%d", getLineNumStart()));
if (columnRecord != null) {
if (columnRecord.getOffsetColumnEnd() != 0L) {
writer.write(String.format("%5d:%5d-%5d-%5d 0x%08x %s", getLineNumStart(),
columnRecord.getOffsetColumnStart(), getLineNumStart() + getDeltaLineEnd(),
columnRecord.getOffsetColumnEnd(), getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
else {
writer.write(String.format("%s-%5d 0x%08x %s", lineStart,
columnRecord.getOffsetColumnStart(), getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
}
else {
writer.write(String.format("%s 0x%08x %s", lineStart, getOffset() + offCon,
(isStatement() ? "Statement" : "Expression")));
}
}
}

View File

@ -24,10 +24,7 @@ import ghidra.util.task.TaskMonitor;
/**
* Abstract class for C13 section types.
*/
abstract class C13Section {
protected static final String dashes =
"------------------------------------------------------------\n";
public abstract class C13Section {
private boolean ignore;
protected C13Section(boolean ignore) {
@ -39,12 +36,14 @@ abstract class C13Section {
}
void dump(Writer writer, TaskMonitor monitor) throws IOException, CancelledException {
String n = getClass().getSimpleName();
int len = n.length();
writer.write(n + dashes.substring(len));
writer.write("End " + n + dashes.substring(len + 4));
PdbReaderUtils.dumpHead(writer, this);
dumpInternal(writer, monitor);
PdbReaderUtils.dumpTail(writer, this);
}
abstract protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException;
/**
* Parse and return a {@link C13Section} of a specific type pointed to by a section record.
* @param reader reader to parse from
@ -63,31 +62,31 @@ abstract class C13Section {
switch (type) {
case SYMBOLS:
return C13Symbols.parse(recordReader, ignore, monitor);
return SymbolsC13Section.parse(recordReader, ignore, monitor);
case LINES:
return C13Lines.parse(recordReader, ignore, monitor);
return LinesC13Section.parse(recordReader, ignore, monitor);
case STRING_TABLE:
return C13StringTable.parse(recordReader, ignore, monitor);
return StringTableC13Section.parse(recordReader, ignore, monitor);
case FILE_CHECKSUMS:
return C13FileChecksums.parse(recordReader, ignore, monitor);
return FileChecksumsC13Section.parse(recordReader, ignore, monitor);
case FRAMEDATA:
return C13FrameData.parse(recordReader, ignore, monitor);
return FrameDataC13Section.parse(recordReader, ignore, monitor);
case INLINEE_LINES:
return C13InlineeLines.parse(recordReader, ignore, monitor);
return InlineeLinesC13Section.parse(recordReader, ignore, monitor);
case CROSS_SCOPE_IMPORTS:
return C13CrossScopeImports.parse(recordReader, ignore, monitor);
return CrossScopeImportsC13Section.parse(recordReader, ignore, monitor);
case CROSS_SCOPE_EXPORTS:
return C13CrossScopeExports.parse(recordReader, ignore, monitor);
return CrossScopeExportsC13Section.parse(recordReader, ignore, monitor);
case IL_LINES:
return C13IlLines.parse(recordReader, ignore, monitor);
return IlLinesC13Section.parse(recordReader, ignore, monitor);
case FUNC_MDTOKEN_MAP:
return C13FuncMdTokenMap.parse(recordReader, ignore, monitor);
return FuncMdTokenMapC13Section.parse(recordReader, ignore, monitor);
case TYPE_MDTOKEN_MAP:
return C13TypeMdTokenMap.parse(recordReader, ignore, monitor);
return TypeMdTokenMapC13Section.parse(recordReader, ignore, monitor);
case MERGED_ASSEMBLY_INPUT:
return C13MergedAssemblyInput.parse(recordReader, ignore, monitor);
return MergedAssemblyInputC13Section.parse(recordReader, ignore, monitor);
case COFF_SYMBOL_RVA: // Relative Virtual Address
return C13CoffSymbolRva.parse(recordReader, ignore, monitor);
return CoffSymbolRvaC13Section.parse(recordReader, ignore, monitor);
default:
return UnknownC13Section.parse(recordReader, ignore, monitor);
}

View File

@ -25,7 +25,7 @@ import ghidra.util.task.TaskMonitor;
* Iterator for {@link C13Section} data being read from C13 section of module stream.
* @param <T> the iterator type
*/
class C13SectionIterator<T extends C13Section> implements ParsingIterator<T> {
public class C13SectionIterator<T extends C13Section> implements ParsingIterator<T> {
private PdbByteReader reader;
private Class<T> clazz;

View File

@ -39,19 +39,19 @@ import ghidra.util.Msg;
enum C13Type {
UNKNOWN(0x80000000, UnknownC13Section.class), // We created; fix/eliminate if causes problems
ALL(0x00000000, C13Section.class), // We created; fix if causes problems
SYMBOLS(0xf1, C13Symbols.class),
LINES(0xf2, C13Lines.class),
STRING_TABLE(0xf3, C13StringTable.class),
FILE_CHECKSUMS(0xf4, C13FileChecksums.class),
FRAMEDATA(0xf5, C13FrameData.class),
INLINEE_LINES(0xf6, C13InlineeLines.class),
CROSS_SCOPE_IMPORTS(0xf7, C13CrossScopeImports.class),
CROSS_SCOPE_EXPORTS(0xf8, C13CrossScopeExports.class),
IL_LINES(0xf9, C13IlLines.class),
FUNC_MDTOKEN_MAP(0xfa, C13FuncMdTokenMap.class),
TYPE_MDTOKEN_MAP(0xfb, C13TypeMdTokenMap.class),
MERGED_ASSEMBLY_INPUT(0xfc, C13MergedAssemblyInput.class),
COFF_SYMBOL_RVA(0xfd, C13CoffSymbolRva.class);
SYMBOLS(0xf1, SymbolsC13Section.class),
LINES(0xf2, LinesC13Section.class),
STRING_TABLE(0xf3, StringTableC13Section.class),
FILE_CHECKSUMS(0xf4, FileChecksumsC13Section.class),
FRAMEDATA(0xf5, FrameDataC13Section.class),
INLINEE_LINES(0xf6, InlineeLinesC13Section.class),
CROSS_SCOPE_IMPORTS(0xf7, CrossScopeImportsC13Section.class),
CROSS_SCOPE_EXPORTS(0xf8, CrossScopeExportsC13Section.class),
IL_LINES(0xf9, IlLinesC13Section.class),
FUNC_MDTOKEN_MAP(0xfa, FuncMdTokenMapC13Section.class),
TYPE_MDTOKEN_MAP(0xfb, TypeMdTokenMapC13Section.class),
MERGED_ASSEMBLY_INPUT(0xfc, MergedAssemblyInputC13Section.class),
COFF_SYMBOL_RVA(0xfd, CoffSymbolRvaC13Section.class);
private static final int IGNORE_BIT = 0x80000000;
private static final int IGNORE_BIT_MASK = ~IGNORE_BIT;
@ -96,11 +96,11 @@ enum C13Type {
return t;
}
public static boolean ignore(int val) {
static boolean ignore(int val) {
return ((val & IGNORE_BIT) != 0);
}
public static int maskIgnore(int val) {
static int maskIgnore(int val) {
return val & IGNORE_BIT_MASK;
}

View File

@ -24,12 +24,13 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13CoffSymbolRva extends AbstractUnimplementedC13Section {
static C13CoffSymbolRva parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13CoffSymbolRva(reader, ignore, monitor);
class CoffSymbolRvaC13Section extends AbstractUnimplementedC13Section {
static CoffSymbolRvaC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor) {
return new CoffSymbolRvaC13Section(reader, ignore, monitor);
}
protected C13CoffSymbolRva(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private CoffSymbolRvaC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -27,12 +27,12 @@ import ghidra.util.task.TaskMonitor;
/**
* PDB C13 Cross-Scope Exports information.
*/
public class C13CrossScopeExports extends C13Section {
public class CrossScopeExportsC13Section extends C13Section {
private List<CrossScopeExport> crossScopeExports = new ArrayList<>();
private List<C13CrossScopeExport> crossScopeExports = new ArrayList<>();
/**
* Parse and return a {@link C13CrossScopeExports}.
* Parse and return a {@link CrossScopeExportsC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @param monitor {@link TaskMonitor} used for checking cancellation
@ -40,26 +40,31 @@ public class C13CrossScopeExports extends C13Section {
* @throws PdbException Upon not enough data left to parse
* @throws CancelledException Upon user cancellation
*/
static C13CrossScopeExports parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
static CrossScopeExportsC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13CrossScopeExports(reader, ignore, monitor);
return new CrossScopeExportsC13Section(reader, ignore, monitor);
}
protected C13CrossScopeExports(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
private CrossScopeExportsC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws CancelledException, PdbException {
super(ignore);
while (reader.numRemaining() >= CrossScopeExport.getBaseRecordSize()) {
while (reader.numRemaining() >= C13CrossScopeExport.getBaseRecordSize()) {
monitor.checkCancelled();
CrossScopeExport crossExport = new CrossScopeExport(reader);
C13CrossScopeExport crossExport = new C13CrossScopeExport(reader);
crossScopeExports.add(crossExport);
}
if (reader.hasMore()) {
Msg.debug(C13CrossScopeExports.class,
Msg.debug(CrossScopeExportsC13Section.class,
String.format("Num Extra C13CrossScopeExports bytes: %d", reader.numRemaining()));
}
}
List<CrossScopeExport> getCrossScopeExports() {
/**
* Returns the cross-scope exports
* @return the corss-scope exports
*/
public List<C13CrossScopeExport> getCrossScopeExports() {
return crossScopeExports;
}
@ -69,48 +74,14 @@ public class C13CrossScopeExports extends C13Section {
crossScopeExports.size());
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13CrossScopeExports----------------------------------------\n");
for (CrossScopeExport crossScopeExport : crossScopeExports) {
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
for (C13CrossScopeExport crossScopeExport : crossScopeExports) {
monitor.checkCancelled();
writer.write(crossScopeExport.toString());
writer.write('\n');
}
writer.write("End C13CrossScopeExports------------------------------------\n");
}
static class CrossScopeExport {
private long localId; // unsigned 32-bit
private long globalId; // unsigned 32-bit
private static int getBaseRecordSize() {
return 8;
}
CrossScopeExport(PdbByteReader reader) throws PdbException {
localId = reader.parseUnsignedIntVal();
globalId = reader.parseUnsignedIntVal();
}
long getLocalId() {
return localId;
}
long getGlobalId() {
return globalId;
}
@Override
public String toString() {
return String.format("0x%08x, 0x%08x", localId, globalId);
}
}
}

View File

@ -0,0 +1,87 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13 Cross-Scope Imports information.... also known as Cross-Scope References.
*/
public class CrossScopeImportsC13Section extends C13Section {
private List<C13CrossScopeImport> crossScopeImports = new ArrayList<>();
/**
* Parse and return a {@link CrossScopeImportsC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static CrossScopeImportsC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor)
throws PdbException, CancelledException {
return new CrossScopeImportsC13Section(reader, ignore, monitor);
}
private CrossScopeImportsC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws CancelledException, PdbException {
super(ignore);
while (reader.numRemaining() >= C13CrossScopeImport.getBaseRecordSize()) {
monitor.checkCancelled();
C13CrossScopeImport crossImport = new C13CrossScopeImport(reader);
crossScopeImports.add(crossImport);
}
if (reader.hasMore()) {
Msg.debug(CrossScopeExportsC13Section.class,
String.format("Num Extra C13CrossScopeExports bytes: %d", reader.numRemaining()));
}
}
/**
* Returns the cross-scope imports
* @return the cross-scope imports
*/
public List<C13CrossScopeImport> getCrossScopeImports() {
return crossScopeImports;
}
@Override
public String toString() {
return String.format("%s: num cross-scope imports = %d", getClass().getSimpleName(),
crossScopeImports.size());
}
@Override
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
for (C13CrossScopeImport crossScopeImport : crossScopeImports) {
monitor.checkCancelled();
writer.write(crossScopeImport.toString());
writer.write('\n');
}
}
}

View File

@ -0,0 +1,86 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13 Module File Checksums.
*/
public class FileChecksumsC13Section extends C13Section {
private List<C13FileChecksum> fileChecksums = new ArrayList<>();
/**
* Parse and return a {@link FileChecksumsC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static FileChecksumsC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new FileChecksumsC13Section(reader, ignore, monitor);
}
private FileChecksumsC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws CancelledException, PdbException {
super(ignore);
while (reader.numRemaining() >= C13FileChecksum.getBaseRecordSize()) {
monitor.checkCancelled();
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
fileChecksums.add(fileChecksum);
}
if (reader.hasMore()) {
Msg.debug(FileChecksumsC13Section.class,
String.format("Num Extra C13FileChecksums bytes: %d", reader.numRemaining()));
}
}
/**
* Returns the C13 file checksum
* @return the checksum
*/
public List<C13FileChecksum> getFileChecksums() {
return fileChecksums;
}
@Override
public String toString() {
return String.format("%s: num checksums = %d", getClass().getSimpleName(),
fileChecksums.size());
}
@Override
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
for (C13FileChecksum checksum : fileChecksums) {
monitor.checkCancelled();
writer.write(checksum.toString());
writer.write('\n');
}
}
}

View File

@ -24,12 +24,12 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13FrameData extends AbstractUnimplementedC13Section {
static C13FrameData parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13FrameData(reader, ignore, monitor);
class FrameDataC13Section extends AbstractUnimplementedC13Section {
static FrameDataC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new FrameDataC13Section(reader, ignore, monitor);
}
protected C13FrameData(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private FrameDataC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -24,12 +24,13 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13FuncMdTokenMap extends AbstractUnimplementedC13Section {
static C13FuncMdTokenMap parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13FuncMdTokenMap(reader, ignore, monitor);
class FuncMdTokenMapC13Section extends AbstractUnimplementedC13Section {
static FuncMdTokenMapC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor) {
return new FuncMdTokenMapC13Section(reader, ignore, monitor);
}
protected C13FuncMdTokenMap(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private FuncMdTokenMapC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -15,21 +15,18 @@
*/
package ghidra.app.util.bin.format.pdb2.pdbreader;
import java.io.IOException;
import java.io.Writer;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* C13IlLines information. This is C13 IL Lines, where "IL" meaning is uncertain... could mean
* Incremental Link. MSFT defers parsing to C13Lines, so it is the same format, which we have
* given to a common parent, {@link AbstractC13Lines}.
* given to a common parent, {@link AbstractLinesC13Section}.
*/
public class C13IlLines extends AbstractC13Lines {
public class IlLinesC13Section extends AbstractLinesC13Section {
/**
* Parse and return a {@link C13IlLines}.
* Parse and return a {@link IlLinesC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @param monitor {@link TaskMonitor} used for checking cancellation
@ -37,26 +34,14 @@ public class C13IlLines extends AbstractC13Lines {
* @throws PdbException Upon not enough data left to parse
* @throws CancelledException Upon user cancellation
*/
static C13IlLines parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
static IlLinesC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13IlLines(reader, ignore, monitor);
return new IlLinesC13Section(reader, ignore, monitor);
}
protected C13IlLines(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
private IlLinesC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(reader, ignore, monitor);
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13IlLines--------------------------------------------------\n");
dumpInternal(writer, monitor);
writer.write("End C13IlLines----------------------------------------------\n");
}
}

View File

@ -0,0 +1,129 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
/**
* PDB C13InlineeLines information.
*/
public class InlineeLinesC13Section extends C13Section {
// These are actually DWORDs, but we are ignoring the unsigned nature and using int.
private static final int InlineeSourceLineSignature = 0x0;
private static final int ExtendedInlineeSourceLineSignature = 0x1;
private int signature; //actually a DWORD (unsigned int)
private List<C13InlineeSourceLine> inlineeLines = new ArrayList<>();
/**
* Parse and return a {@link InlineeLinesC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @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
*/
static InlineeLinesC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new InlineeLinesC13Section(reader, ignore, monitor);
}
private static List<C13InlineeSourceLine> parseInlineeLines(PdbByteReader reader,
TaskMonitor monitor) throws CancelledException, PdbException {
List<C13InlineeSourceLine> lines = new ArrayList<>();
while (reader.numRemaining() >= C13InlineeSourceLine.getBaseRecordSize()) {
monitor.checkCancelled();
C13InlineeSourceLine line = new C13InlineeSourceLine(reader);
lines.add(line);
}
return lines;
}
private static List<C13InlineeSourceLine> parseExtendedInlineeLines(PdbByteReader reader,
TaskMonitor monitor) throws CancelledException, PdbException {
List<C13InlineeSourceLine> lines = new ArrayList<>();
while (reader.numRemaining() >= C13ExtendedInlineeSourceLine.getBaseRecordSize()) {
monitor.checkCancelled();
C13ExtendedInlineeSourceLine line = new C13ExtendedInlineeSourceLine(reader, monitor);
lines.add(line);
}
return lines;
}
private InlineeLinesC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(ignore);
signature = reader.parseInt(); //actually a DWORD (unsigned int)
switch (signature) {
case InlineeSourceLineSignature:
inlineeLines = parseInlineeLines(reader, monitor);
break;
case ExtendedInlineeSourceLineSignature:
inlineeLines = parseExtendedInlineeLines(reader, monitor);
break;
default:
inlineeLines = new ArrayList<>();
break;
}
if (reader.hasMore()) {
Msg.debug(InlineeLinesC13Section.class,
String.format("Extra inlinee bytes remain for signature: 0x%03x", signature));
}
}
/**
* Returns the signature. Not sure how to interpret the signature at this time
* @return the signature
*/
public int getSignature() {
return signature;
}
/**
* Returns the inlinee source lines
* @return the inlinee source lines
*/
public List<C13InlineeSourceLine> getInlineeLines() {
return inlineeLines;
}
@Override
public String toString() {
return String.format("%s: num inlinee lines = %d", getClass().getSimpleName(),
inlineeLines.size());
}
@Override
protected void dumpInternal(Writer writer, TaskMonitor monitor)
throws IOException, CancelledException {
writer.write(String.format("Signature: 0x%03x\n", signature));
for (C13InlineeSourceLine line : inlineeLines) {
monitor.checkCancelled();
writer.write(line.toString());
writer.write('\n');
}
}
}

View File

@ -15,9 +15,6 @@
*/
package ghidra.app.util.bin.format.pdb2.pdbreader;
import java.io.IOException;
import java.io.Writer;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@ -27,10 +24,10 @@ import ghidra.util.task.TaskMonitor;
* information for "type" 0xf2 (and maybe 0xf4) can be found after the symbol information in
* module debug streams.
*/
public class C13Lines extends AbstractC13Lines {
public class LinesC13Section extends AbstractLinesC13Section {
/**
* Parse and return a {@link C13Lines}.
* Parse and return a {@link LinesC13Section}.
* @param reader {@link PdbByteReader} containing the symbol records to deserialize
* @param ignore flag indicating whether the record should be ignored
* @param monitor {@link TaskMonitor} used for checking cancellation
@ -38,27 +35,14 @@ public class C13Lines extends AbstractC13Lines {
* @throws PdbException Upon not enough data left to parse
* @throws CancelledException Upon user cancellation
*/
static C13Lines parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
static LinesC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
return new C13Lines(reader, ignore, monitor);
return new LinesC13Section(reader, ignore, monitor);
}
protected C13Lines(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
private LinesC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor)
throws PdbException, CancelledException {
super(reader, ignore, monitor);
}
/**
* Dumps this class to a Writer
* @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, TaskMonitor monitor) throws IOException, CancelledException {
writer.write("C13Lines----------------------------------------------------\n");
dumpInternal(writer, monitor);
writer.write("End C13Lines------------------------------------------------\n");
}
}

View File

@ -24,13 +24,13 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13MergedAssemblyInput extends AbstractUnimplementedC13Section {
static C13MergedAssemblyInput parse(PdbByteReader reader, boolean ignore,
class MergedAssemblyInputC13Section extends AbstractUnimplementedC13Section {
static MergedAssemblyInputC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor) {
return new C13MergedAssemblyInput(reader, ignore, monitor);
return new MergedAssemblyInputC13Section(reader, ignore, monitor);
}
protected C13MergedAssemblyInput(PdbByteReader reader, boolean ignore,
private MergedAssemblyInputC13Section(PdbByteReader reader, boolean ignore,
TaskMonitor monitor) {
super(reader, ignore, monitor);
}

View File

@ -0,0 +1,44 @@
/* ###
* 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;
import java.io.IOException;
import java.io.Writer;
/**
* Utils for PdbReader
*/
public class PdbReaderUtils {
private static final String dashes =
"------------------------------------------------------------\n";
private PdbReaderUtils() {
// Do nothing
}
public static void dumpHead(Writer writer, Object obj) throws IOException {
String name = obj.getClass().getSimpleName();
int len = name.length();
writer.write(name + dashes.substring(len));
}
public static void dumpTail(Writer writer, Object obj) throws IOException {
String name = obj.getClass().getSimpleName();
int len = name.length();
writer.write("End " + name + dashes.substring(len + 4));
}
}

View File

@ -24,12 +24,12 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13StringTable extends AbstractUnimplementedC13Section {
static C13StringTable parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13StringTable(reader, ignore, monitor);
class StringTableC13Section extends AbstractUnimplementedC13Section {
static StringTableC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new StringTableC13Section(reader, ignore, monitor);
}
protected C13StringTable(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private StringTableC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -24,12 +24,12 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13Symbols extends AbstractUnimplementedC13Section {
static C13Symbols parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13Symbols(reader, ignore, monitor);
class SymbolsC13Section extends AbstractUnimplementedC13Section {
static SymbolsC13Section parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new SymbolsC13Section(reader, ignore, monitor);
}
protected C13Symbols(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private SymbolsC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -24,12 +24,13 @@ import ghidra.util.task.TaskMonitor;
* but this should be changed to {@link C13Section} when the format is understood and the
* implementation is made concrete.
*/
class C13TypeMdTokenMap extends AbstractUnimplementedC13Section {
static C13TypeMdTokenMap parse(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
return new C13TypeMdTokenMap(reader, ignore, monitor);
class TypeMdTokenMapC13Section extends AbstractUnimplementedC13Section {
static TypeMdTokenMapC13Section parse(PdbByteReader reader, boolean ignore,
TaskMonitor monitor) {
return new TypeMdTokenMapC13Section(reader, ignore, monitor);
}
protected C13TypeMdTokenMap(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private TypeMdTokenMapC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -25,7 +25,7 @@ class UnknownC13Section extends AbstractUnimplementedC13Section {
return new UnknownC13Section(reader, ignore, monitor);
}
protected UnknownC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
private UnknownC13Section(PdbByteReader reader, boolean ignore, TaskMonitor monitor) {
super(reader, ignore, monitor);
}
}

View File

@ -23,7 +23,6 @@ import org.junit.Before;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.app.util.bin.format.pdb2.pdbreader.C13FileChecksums.FileChecksum;
import ghidra.util.task.TaskMonitor;
/**
@ -47,82 +46,85 @@ public class C13SectionsTest extends AbstractGenericTest {
assertEquals(C13Type.SYMBOLS, C13Type.fromValue(0xf1));
assertTrue(C13Type.ignore(0xf1 | ignore));
assertEquals(C13Type.SYMBOLS, C13Type.fromValue(0xf1 | ignore));
assertEquals(C13Type.SYMBOLS, C13Type.fromClassValue(C13Symbols.class));
assertEquals(C13Type.SYMBOLS, C13Type.fromClassValue(SymbolsC13Section.class));
assertFalse(C13Type.ignore(0xf2));
assertEquals(C13Type.LINES, C13Type.fromValue(0xf2));
assertTrue(C13Type.ignore(0xf2 | ignore));
assertEquals(C13Type.LINES, C13Type.fromValue(0xf2 | ignore));
assertEquals(C13Type.LINES, C13Type.fromClassValue(C13Lines.class));
assertEquals(C13Type.LINES, C13Type.fromClassValue(LinesC13Section.class));
assertFalse(C13Type.ignore(0xf3));
assertEquals(C13Type.STRING_TABLE, C13Type.fromValue(0xf3));
assertTrue(C13Type.ignore(0xf3 | ignore));
assertEquals(C13Type.STRING_TABLE, C13Type.fromValue(0xf3 | ignore));
assertEquals(C13Type.STRING_TABLE, C13Type.fromClassValue(C13StringTable.class));
assertEquals(C13Type.STRING_TABLE, C13Type.fromClassValue(StringTableC13Section.class));
assertFalse(C13Type.ignore(0xf4));
assertEquals(C13Type.FILE_CHECKSUMS, C13Type.fromValue(0xf4));
assertTrue(C13Type.ignore(0xf4 | ignore));
assertEquals(C13Type.FILE_CHECKSUMS, C13Type.fromValue(0xf4 | ignore));
assertEquals(C13Type.FILE_CHECKSUMS, C13Type.fromClassValue(C13FileChecksums.class));
assertEquals(C13Type.FILE_CHECKSUMS, C13Type.fromClassValue(FileChecksumsC13Section.class));
assertFalse(C13Type.ignore(0xf5));
assertEquals(C13Type.FRAMEDATA, C13Type.fromValue(0xf5));
assertTrue(C13Type.ignore(0xf5 | ignore));
assertEquals(C13Type.FRAMEDATA, C13Type.fromValue(0xf5 | ignore));
assertEquals(C13Type.FRAMEDATA, C13Type.fromClassValue(C13FrameData.class));
assertEquals(C13Type.FRAMEDATA, C13Type.fromClassValue(FrameDataC13Section.class));
assertFalse(C13Type.ignore(0xf6));
assertEquals(C13Type.INLINEE_LINES, C13Type.fromValue(0xf6));
assertTrue(C13Type.ignore(0xf6 | ignore));
assertEquals(C13Type.INLINEE_LINES, C13Type.fromValue(0xf6 | ignore));
assertEquals(C13Type.INLINEE_LINES, C13Type.fromClassValue(C13InlineeLines.class));
assertEquals(C13Type.INLINEE_LINES, C13Type.fromClassValue(InlineeLinesC13Section.class));
assertFalse(C13Type.ignore(0xf7));
assertEquals(C13Type.CROSS_SCOPE_IMPORTS, C13Type.fromValue(0xf7));
assertTrue(C13Type.ignore(0xf7 | ignore));
assertEquals(C13Type.CROSS_SCOPE_IMPORTS, C13Type.fromValue(0xf7 | ignore));
assertEquals(C13Type.CROSS_SCOPE_IMPORTS,
C13Type.fromClassValue(C13CrossScopeImports.class));
C13Type.fromClassValue(CrossScopeImportsC13Section.class));
assertFalse(C13Type.ignore(0xf8));
assertEquals(C13Type.CROSS_SCOPE_EXPORTS, C13Type.fromValue(0xf8));
assertTrue(C13Type.ignore(0xf8 | ignore));
assertEquals(C13Type.CROSS_SCOPE_EXPORTS, C13Type.fromValue(0xf8 | ignore));
assertEquals(C13Type.CROSS_SCOPE_EXPORTS,
C13Type.fromClassValue(C13CrossScopeExports.class));
C13Type.fromClassValue(CrossScopeExportsC13Section.class));
assertFalse(C13Type.ignore(0xf9));
assertEquals(C13Type.IL_LINES, C13Type.fromValue(0xf9));
assertTrue(C13Type.ignore(0xf9 | ignore));
assertEquals(C13Type.IL_LINES, C13Type.fromValue(0xf9 | ignore));
assertEquals(C13Type.IL_LINES, C13Type.fromClassValue(C13IlLines.class));
assertEquals(C13Type.IL_LINES, C13Type.fromClassValue(IlLinesC13Section.class));
assertFalse(C13Type.ignore(0xfa));
assertEquals(C13Type.FUNC_MDTOKEN_MAP, C13Type.fromValue(0xfa));
assertTrue(C13Type.ignore(0xfa | ignore));
assertEquals(C13Type.FUNC_MDTOKEN_MAP, C13Type.fromValue(0xfa | ignore));
assertEquals(C13Type.FUNC_MDTOKEN_MAP, C13Type.fromClassValue(C13FuncMdTokenMap.class));
assertEquals(C13Type.FUNC_MDTOKEN_MAP,
C13Type.fromClassValue(FuncMdTokenMapC13Section.class));
assertFalse(C13Type.ignore(0xfb));
assertEquals(C13Type.TYPE_MDTOKEN_MAP, C13Type.fromValue(0xfb));
assertTrue(C13Type.ignore(0xfb | ignore));
assertEquals(C13Type.TYPE_MDTOKEN_MAP, C13Type.fromValue(0xfb | ignore));
assertEquals(C13Type.TYPE_MDTOKEN_MAP, C13Type.fromClassValue(C13TypeMdTokenMap.class));
assertEquals(C13Type.TYPE_MDTOKEN_MAP,
C13Type.fromClassValue(TypeMdTokenMapC13Section.class));
assertFalse(C13Type.ignore(0xfc));
assertEquals(C13Type.MERGED_ASSEMBLY_INPUT, C13Type.fromValue(0xfc));
assertTrue(C13Type.ignore(0xfc | ignore));
assertEquals(C13Type.MERGED_ASSEMBLY_INPUT, C13Type.fromValue(0xfc | ignore));
assertEquals(C13Type.MERGED_ASSEMBLY_INPUT,
C13Type.fromClassValue(C13MergedAssemblyInput.class));
C13Type.fromClassValue(MergedAssemblyInputC13Section.class));
assertFalse(C13Type.ignore(0xfd));
assertEquals(C13Type.COFF_SYMBOL_RVA, C13Type.fromValue(0xfd));
assertTrue(C13Type.ignore(0xfd | ignore));
assertEquals(C13Type.COFF_SYMBOL_RVA, C13Type.fromValue(0xfd | ignore));
assertEquals(C13Type.COFF_SYMBOL_RVA, C13Type.fromClassValue(C13CoffSymbolRva.class));
assertEquals(C13Type.COFF_SYMBOL_RVA,
C13Type.fromClassValue(CoffSymbolRvaC13Section.class));
//---------------------------
@ -140,7 +142,7 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13NoneFileChecksum() throws Exception {
byte[] bytes = createC13NoneFileChecksumBytes(0x1000);
PdbByteReader reader = new PdbByteReader(bytes);
FileChecksum fileChecksum = new FileChecksum(reader);
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
String result = fileChecksum.toString();
assertEquals("0x00001000, 0x00 NoneChecksumType(00): ", result);
}
@ -149,7 +151,7 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13Md5FileChecksum() throws Exception {
byte[] bytes = createC13Md5FileChecksumBytes(0x1010);
PdbByteReader reader = new PdbByteReader(bytes);
FileChecksum fileChecksum = new FileChecksum(reader);
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
String result = fileChecksum.toString();
assertEquals("0x00001010, 0x10 Md5ChecksumType(01): " + "554433221100ffeeddccbbaa99887766",
result);
@ -159,7 +161,7 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13Sha1FileChecksum() throws Exception {
byte[] bytes = createC13Sha1FileChecksumBytes(0x1020);
PdbByteReader reader = new PdbByteReader(bytes);
FileChecksum fileChecksum = new FileChecksum(reader);
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
String result = fileChecksum.toString();
assertEquals(
"0x00001020, 0x28 Sha1ChecksumType(02): " +
@ -171,7 +173,7 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13Sha256FileChecksum() throws Exception {
byte[] bytes = createC13Sha256FileChecksumBytes(0x1030);
PdbByteReader reader = new PdbByteReader(bytes);
FileChecksum fileChecksum = new FileChecksum(reader);
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
String result = fileChecksum.toString();
//@formatter:off
assertEquals(
@ -187,7 +189,7 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] bytes =
createC13FileChecksumBytes(0x1040, 0x04, new byte[] { 0x33, 0x44, 0x55, 0x66 });
PdbByteReader reader = new PdbByteReader(bytes);
FileChecksum fileChecksum = new FileChecksum(reader);
C13FileChecksum fileChecksum = new C13FileChecksum(reader);
String result = fileChecksum.toString();
assertEquals("0x00001040, 0x04 UnknownChecksumType(04): 33445566", result);
}
@ -207,12 +209,12 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13FileChecksums() throws Exception {
PdbByteReader reader = new PdbByteReader(createC13FileChecksumsSectionBytes(0));
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13FileChecksums);
assertTrue(section instanceof FileChecksumsC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13FileChecksums--------------------------------------------\n" +
"FileChecksumsC13Section-------------------------------------\n" +
"0x00002000, 0x00 NoneChecksumType(00): \n" +
"0x00002010, 0x00 NoneChecksumType(00): \n" +
"0x00002020, 0x10 Md5ChecksumType(01): 554433221100ffeeddccbbaa99887766\n" +
@ -227,7 +229,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"0x00002070, 0x40 Sha256ChecksumType(03): 00225566002255660022556600225566" +
"002255660022556600225566002255660022556600225566002255660022556600225566" +
"002255660022556600225566\n" +
"End C13FileChecksums----------------------------------------\n",
"End FileChecksumsC13Section---------------------------------\n",
writer.toString());
//@formatter:on
}
@ -341,12 +343,12 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13LinesSectionBytes = createC13LinesSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13LinesSectionBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13Lines);
assertTrue(section instanceof LinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13Lines----------------------------------------------------\n" +
"LinesC13Section---------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004100 Statement\n" +
@ -355,7 +357,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13Lines------------------------------------------------\n",
"End LinesC13Section-----------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -365,12 +367,12 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13LinesSectionBytes = createC13LinesWithColumnsSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13LinesSectionBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13Lines);
assertTrue(section instanceof LinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13Lines----------------------------------------------------\n" +
"LinesC13Section---------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000001 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 48\n" +
" 16: 0- 16- 1 0x00004100 Statement\n" +
@ -379,7 +381,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 36\n" +
" 32: 0- 32- 1 0x00004200 Expression\n" +
" 33: 2- 34- 3 0x00004201 Expression\n" +
"End C13Lines------------------------------------------------\n",
"End LinesC13Section-----------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -389,12 +391,12 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13LinesSectionBytes = createC13IlLinesSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13LinesSectionBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13IlLines);
assertTrue(section instanceof IlLinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13IlLines--------------------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004100 Statement\n" +
@ -403,7 +405,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n",
"End IlLinesC13Section---------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -413,12 +415,12 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13LinesSectionBytes = createC13IlLinesWithColumnsSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13LinesSectionBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13IlLines);
assertTrue(section instanceof IlLinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13IlLines--------------------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000001 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 48\n" +
" 16: 0- 16- 1 0x00004100 Statement\n" +
@ -427,7 +429,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 36\n" +
" 32: 0- 32- 1 0x00004200 Expression\n" +
" 33: 2- 34- 3 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n",
"End IlLinesC13Section---------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -592,15 +594,15 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13CrossScopeExportsBytes = createC13CrossExportSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13CrossScopeExportsBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13CrossScopeExports);
assertTrue(section instanceof CrossScopeExportsC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13CrossScopeExports----------------------------------------\n" +
"CrossScopeExportsC13Section---------------------------------\n" +
"0x00000100, 0x00001000\n" +
"0x00000101, 0x00001001\n" +
"End C13CrossScopeExports------------------------------------\n",
"End CrossScopeExportsC13Section-----------------------------\n",
writer.toString());
//@formatter:on
}
@ -626,15 +628,15 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13CrossScopeImportsBytes = createC13CrossImportSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13CrossScopeImportsBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13CrossScopeImports);
assertTrue(section instanceof CrossScopeImportsC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13CrossScopeImports----------------------------------------\n" +
"CrossScopeImportsC13Section---------------------------------\n" +
"0x00000100, 1 0x00001000\n" +
"0x00000101, 2 0x00002000 0x00002001\n" +
"End C13CrossScopeImports------------------------------------\n",
"End CrossScopeImportsC13Section-----------------------------\n",
writer.toString());
//@formatter:on
}
@ -664,16 +666,16 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13InlineeBytes = createC13InlineeLinesSectionBytes(0);
PdbByteReader reader = new PdbByteReader(C13InlineeBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13InlineeLines);
assertTrue(section instanceof InlineeLinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13InlineeLines---------------------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x000\n" +
"0x000001000, 0x000001, 256\n" +
"0x000002000, 0x000002, 512\n" +
"End C13InlineeLines-----------------------------------------\n",
"End InlineeLinesC13Section----------------------------------\n",
writer.toString());
//@formatter:on
}
@ -683,16 +685,16 @@ public class C13SectionsTest extends AbstractGenericTest {
byte[] C13InlineeBytes = createC13ExtednedInlineeLinesSectionBytes();
PdbByteReader reader = new PdbByteReader(C13InlineeBytes);
C13Section section = C13Section.parse(reader, TaskMonitor.DUMMY);
assertTrue(section instanceof C13InlineeLines);
assertTrue(section instanceof InlineeLinesC13Section);
StringWriter writer = new StringWriter();
section.dump(writer, TaskMonitor.DUMMY);
//@formatter:off
assertEquals(
"C13InlineeLines---------------------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x001\n" +
"0x000001000, 0x000001, 256\n" +
"0x000002000, 0x000002, 512 0x000003 0x000004\n" +
"End C13InlineeLines-----------------------------------------\n",
"End InlineeLinesC13Section----------------------------------\n",
writer.toString());
//@formatter:on
}
@ -744,46 +746,46 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13StringTableSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13StringTable> iterator =
new C13SectionIterator<>(reader, C13StringTable.class, true, TaskMonitor.DUMMY);
C13SectionIterator<StringTableC13Section> iterator =
new C13SectionIterator<>(reader, StringTableC13Section.class, true, TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13StringTable----------------------------------------------\n" +
"StringTableC13Section---------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13StringTable------------------------------------------\n" +
"C13StringTable----------------------------------------------\n" +
"End StringTableC13Section-----------------------------------\n" +
"StringTableC13Section---------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13StringTable------------------------------------------\n" +
"C13StringTable----------------------------------------------\n" +
"End StringTableC13Section-----------------------------------\n" +
"StringTableC13Section---------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13StringTable------------------------------------------\n" +
"C13StringTable----------------------------------------------\n" +
"End StringTableC13Section-----------------------------------\n" +
"StringTableC13Section---------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13StringTable------------------------------------------\n",
"End StringTableC13Section-----------------------------------\n",
writer.toString());
//@formatter:on
}
@ -792,15 +794,16 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13FileChecksumsSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13FileChecksums> iterator =
new C13SectionIterator<>(reader, C13FileChecksums.class, true, TaskMonitor.DUMMY);
C13SectionIterator<FileChecksumsC13Section> iterator =
new C13SectionIterator<>(reader, FileChecksumsC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13FileChecksums--------------------------------------------\n" +
"FileChecksumsC13Section-------------------------------------\n" +
"0x00002000, 0x00 NoneChecksumType(00): \n" +
"0x00002010, 0x00 NoneChecksumType(00): \n" +
"0x00002020, 0x10 Md5ChecksumType(01): 554433221100ffeeddccbbaa99887766\n" +
@ -815,8 +818,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"0x00002070, 0x40 Sha256ChecksumType(03): 00225566002255660022556600225566" +
"002255660022556600225566002255660022556600225566002255660022556600225566" +
"002255660022556600225566\n" +
"End C13FileChecksums----------------------------------------\n" +
"C13FileChecksums--------------------------------------------\n" +
"End FileChecksumsC13Section---------------------------------\n" +
"FileChecksumsC13Section-------------------------------------\n" +
"0x00002001, 0x00 NoneChecksumType(00): \n" +
"0x00002011, 0x00 NoneChecksumType(00): \n" +
"0x00002021, 0x10 Md5ChecksumType(01): 554433221100ffeeddccbbaa99887766\n" +
@ -831,8 +834,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"0x00002071, 0x40 Sha256ChecksumType(03): 00225566002255660022556600225566" +
"002255660022556600225566002255660022556600225566002255660022556600225566" +
"002255660022556600225566\n" +
"End C13FileChecksums----------------------------------------\n" +
"C13FileChecksums--------------------------------------------\n" +
"End FileChecksumsC13Section---------------------------------\n" +
"FileChecksumsC13Section-------------------------------------\n" +
"0x00002002, 0x00 NoneChecksumType(00): \n" +
"0x00002012, 0x00 NoneChecksumType(00): \n" +
"0x00002022, 0x10 Md5ChecksumType(01): 554433221100ffeeddccbbaa99887766\n" +
@ -847,8 +850,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"0x00002072, 0x40 Sha256ChecksumType(03): 00225566002255660022556600225566" +
"002255660022556600225566002255660022556600225566002255660022556600225566" +
"002255660022556600225566\n" +
"End C13FileChecksums----------------------------------------\n" +
"C13FileChecksums--------------------------------------------\n" +
"End FileChecksumsC13Section---------------------------------\n" +
"FileChecksumsC13Section-------------------------------------\n" +
"0x00002003, 0x00 NoneChecksumType(00): \n" +
"0x00002013, 0x00 NoneChecksumType(00): \n" +
"0x00002023, 0x10 Md5ChecksumType(01): 554433221100ffeeddccbbaa99887766\n" +
@ -863,7 +866,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"0x00002073, 0x40 Sha256ChecksumType(03): 00225566002255660022556600225566" +
"002255660022556600225566002255660022556600225566002255660022556600225566" +
"002255660022556600225566\n" +
"End C13FileChecksums----------------------------------------\n",
"End FileChecksumsC13Section---------------------------------\n",
writer.toString());
//@formatter:on
}
@ -872,46 +875,46 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13FrameDataSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13FrameData> iterator =
new C13SectionIterator<>(reader, C13FrameData.class, true, TaskMonitor.DUMMY);
C13SectionIterator<FrameDataC13Section> iterator =
new C13SectionIterator<>(reader, FrameDataC13Section.class, true, TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13FrameData------------------------------------------------\n" +
"FrameDataC13Section-----------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13FrameData--------------------------------------------\n" +
"C13FrameData------------------------------------------------\n" +
"End FrameDataC13Section-------------------------------------\n" +
"FrameDataC13Section-----------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13FrameData--------------------------------------------\n" +
"C13FrameData------------------------------------------------\n" +
"End FrameDataC13Section-------------------------------------\n" +
"FrameDataC13Section-----------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13FrameData--------------------------------------------\n" +
"C13FrameData------------------------------------------------\n" +
"End FrameDataC13Section-------------------------------------\n" +
"FrameDataC13Section-----------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13FrameData--------------------------------------------\n",
"End FrameDataC13Section-------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -920,34 +923,34 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13InlineeLinesSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13InlineeLines> iterator =
new C13SectionIterator<>(reader, C13InlineeLines.class, true, TaskMonitor.DUMMY);
C13SectionIterator<InlineeLinesC13Section> iterator =
new C13SectionIterator<>(reader, InlineeLinesC13Section.class, true, TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13InlineeLines---------------------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x000\n" +
"0x000001000, 0x000001, 256\n" +
"0x000002000, 0x000002, 512\n" +
"End C13InlineeLines-----------------------------------------\n" +
"C13InlineeLines---------------------------------------------\n" +
"End InlineeLinesC13Section----------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x000\n" +
"0x000001001, 0x000001, 256\n" +
"0x000002001, 0x000002, 512\n" +
"End C13InlineeLines-----------------------------------------\n" +
"C13InlineeLines---------------------------------------------\n" +
"End InlineeLinesC13Section----------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x000\n" +
"0x000001002, 0x000001, 256\n" +
"0x000002002, 0x000002, 512\n" +
"End C13InlineeLines-----------------------------------------\n" +
"C13InlineeLines---------------------------------------------\n" +
"End InlineeLinesC13Section----------------------------------\n" +
"InlineeLinesC13Section--------------------------------------\n" +
"Signature: 0x000\n" +
"0x000001003, 0x000001, 256\n" +
"0x000002003, 0x000002, 512\n" +
"End C13InlineeLines-----------------------------------------\n",
"End InlineeLinesC13Section----------------------------------\n",
writer.toString());
//@formatter:on
}
@ -956,30 +959,31 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13CrossScopeImportsSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13CrossScopeImports> iterator =
new C13SectionIterator<>(reader, C13CrossScopeImports.class, true, TaskMonitor.DUMMY);
C13SectionIterator<CrossScopeImportsC13Section> iterator =
new C13SectionIterator<>(reader, CrossScopeImportsC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13CrossScopeImports----------------------------------------\n" +
"CrossScopeImportsC13Section---------------------------------\n" +
"0x00000100, 1 0x00001000\n" +
"0x00000101, 2 0x00002000 0x00002001\n" +
"End C13CrossScopeImports------------------------------------\n" +
"C13CrossScopeImports----------------------------------------\n" +
"End CrossScopeImportsC13Section-----------------------------\n" +
"CrossScopeImportsC13Section---------------------------------\n" +
"0x00000101, 1 0x00001000\n" +
"0x00000102, 2 0x00002000 0x00002001\n" +
"End C13CrossScopeImports------------------------------------\n" +
"C13CrossScopeImports----------------------------------------\n" +
"End CrossScopeImportsC13Section-----------------------------\n" +
"CrossScopeImportsC13Section---------------------------------\n" +
"0x00000102, 1 0x00001000\n" +
"0x00000103, 2 0x00002000 0x00002001\n" +
"End C13CrossScopeImports------------------------------------\n" +
"C13CrossScopeImports----------------------------------------\n" +
"End CrossScopeImportsC13Section-----------------------------\n" +
"CrossScopeImportsC13Section---------------------------------\n" +
"0x00000103, 1 0x00001000\n" +
"0x00000104, 2 0x00002000 0x00002001\n" +
"End C13CrossScopeImports------------------------------------\n",
"End CrossScopeImportsC13Section-----------------------------\n",
writer.toString());
//@formatter:on
}
@ -988,30 +992,31 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13CrossScopeExportsSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13CrossScopeExports> iterator =
new C13SectionIterator<>(reader, C13CrossScopeExports.class, true, TaskMonitor.DUMMY);
C13SectionIterator<CrossScopeExportsC13Section> iterator =
new C13SectionIterator<>(reader, CrossScopeExportsC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13CrossScopeExports----------------------------------------\n" +
"CrossScopeExportsC13Section---------------------------------\n" +
"0x00000100, 0x00001000\n" +
"0x00000101, 0x00001001\n" +
"End C13CrossScopeExports------------------------------------\n" +
"C13CrossScopeExports----------------------------------------\n" +
"End CrossScopeExportsC13Section-----------------------------\n" +
"CrossScopeExportsC13Section---------------------------------\n" +
"0x00000101, 0x00001000\n" +
"0x00000102, 0x00001001\n" +
"End C13CrossScopeExports------------------------------------\n" +
"C13CrossScopeExports----------------------------------------\n" +
"End CrossScopeExportsC13Section-----------------------------\n" +
"CrossScopeExportsC13Section---------------------------------\n" +
"0x00000102, 0x00001000\n" +
"0x00000103, 0x00001001\n" +
"End C13CrossScopeExports------------------------------------\n" +
"C13CrossScopeExports----------------------------------------\n" +
"End CrossScopeExportsC13Section-----------------------------\n" +
"CrossScopeExportsC13Section---------------------------------\n" +
"0x00000103, 0x00001000\n" +
"0x00000104, 0x00001001\n" +
"End C13CrossScopeExports------------------------------------\n",
"End CrossScopeExportsC13Section-----------------------------\n",
writer.toString());
//@formatter:on
}
@ -1020,15 +1025,15 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13IlLinesSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13IlLines> iterator =
new C13SectionIterator<>(reader, C13IlLines.class, true, TaskMonitor.DUMMY);
C13SectionIterator<IlLinesC13Section> iterator =
new C13SectionIterator<>(reader, IlLinesC13Section.class, true, TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13IlLines--------------------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004100 Statement\n" +
@ -1037,8 +1042,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n" +
"C13IlLines--------------------------------------------------\n" +
"End IlLinesC13Section---------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004101 Statement\n" +
@ -1047,8 +1052,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n" +
"C13IlLines--------------------------------------------------\n" +
"End IlLinesC13Section---------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004102 Statement\n" +
@ -1057,8 +1062,8 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n" +
"C13IlLines--------------------------------------------------\n" +
"End IlLinesC13Section---------------------------------------\n" +
"IlLinesC13Section-------------------------------------------\n" +
"offCon: 0x00004000 segCon: 1 flags: 0x00000000 lenCon: 0x00000010\n" +
"fileId: 001000, nLines: 3, lenFileBlock: 36\n" +
"16 0x00004103 Statement\n" +
@ -1067,7 +1072,7 @@ public class C13SectionsTest extends AbstractGenericTest {
"fileId: 002000, nLines: 2, lenFileBlock: 28\n" +
"32 0x00004200 Expression\n" +
"33 0x00004201 Expression\n" +
"End C13IlLines----------------------------------------------\n",
"End IlLinesC13Section---------------------------------------\n",
writer.toString());
//@formatter:on
}
@ -1076,46 +1081,47 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13FuncMdTokenMapSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13FuncMdTokenMap> iterator =
new C13SectionIterator<>(reader, C13FuncMdTokenMap.class, true, TaskMonitor.DUMMY);
C13SectionIterator<FuncMdTokenMapC13Section> iterator =
new C13SectionIterator<>(reader, FuncMdTokenMapC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13FuncMdTokenMap-------------------------------------------\n" +
"FuncMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13FuncMdTokenMap---------------------------------------\n" +
"C13FuncMdTokenMap-------------------------------------------\n" +
"End FuncMdTokenMapC13Section--------------------------------\n" +
"FuncMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13FuncMdTokenMap---------------------------------------\n" +
"C13FuncMdTokenMap-------------------------------------------\n" +
"End FuncMdTokenMapC13Section--------------------------------\n" +
"FuncMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13FuncMdTokenMap---------------------------------------\n" +
"C13FuncMdTokenMap-------------------------------------------\n" +
"End FuncMdTokenMapC13Section--------------------------------\n" +
"FuncMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13FuncMdTokenMap---------------------------------------\n",
"End FuncMdTokenMapC13Section--------------------------------\n",
writer.toString());
//@formatter:on
}
@ -1124,46 +1130,47 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13TypeMdTokenMapSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13TypeMdTokenMap> iterator =
new C13SectionIterator<>(reader, C13TypeMdTokenMap.class, true, TaskMonitor.DUMMY);
C13SectionIterator<TypeMdTokenMapC13Section> iterator =
new C13SectionIterator<>(reader, TypeMdTokenMapC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13TypeMdTokenMap-------------------------------------------\n" +
"TypeMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13TypeMdTokenMap---------------------------------------\n" +
"C13TypeMdTokenMap-------------------------------------------\n" +
"End TypeMdTokenMapC13Section--------------------------------\n" +
"TypeMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13TypeMdTokenMap---------------------------------------\n" +
"C13TypeMdTokenMap-------------------------------------------\n" +
"End TypeMdTokenMapC13Section--------------------------------\n" +
"TypeMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13TypeMdTokenMap---------------------------------------\n" +
"C13TypeMdTokenMap-------------------------------------------\n" +
"End TypeMdTokenMapC13Section--------------------------------\n" +
"TypeMdTokenMapC13Section------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13TypeMdTokenMap---------------------------------------\n",
"End TypeMdTokenMapC13Section--------------------------------\n",
writer.toString());
//@formatter:on
}
@ -1172,46 +1179,47 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13MergedAssemblyInputSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13MergedAssemblyInput> iterator =
new C13SectionIterator<>(reader, C13MergedAssemblyInput.class, true, TaskMonitor.DUMMY);
C13SectionIterator<MergedAssemblyInputC13Section> iterator =
new C13SectionIterator<>(reader, MergedAssemblyInputC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13MergedAssemblyInput--------------------------------------\n" +
"MergedAssemblyInputC13Section-------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13MergedAssemblyInput----------------------------------\n" +
"C13MergedAssemblyInput--------------------------------------\n" +
"End MergedAssemblyInputC13Section---------------------------\n" +
"MergedAssemblyInputC13Section-------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13MergedAssemblyInput----------------------------------\n" +
"C13MergedAssemblyInput--------------------------------------\n" +
"End MergedAssemblyInputC13Section---------------------------\n" +
"MergedAssemblyInputC13Section-------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13MergedAssemblyInput----------------------------------\n" +
"C13MergedAssemblyInput--------------------------------------\n" +
"End MergedAssemblyInputC13Section---------------------------\n" +
"MergedAssemblyInputC13Section-------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13MergedAssemblyInput----------------------------------\n",
"End MergedAssemblyInputC13Section---------------------------\n",
writer.toString());
//@formatter:on
}
@ -1220,46 +1228,47 @@ public class C13SectionsTest extends AbstractGenericTest {
public void testC13CoffSymbolRvaSectionIterator() throws Exception {
PdbByteReader reader = new PdbByteReader(c13SectionsBytes);
StringWriter writer = new StringWriter();
C13SectionIterator<C13CoffSymbolRva> iterator =
new C13SectionIterator<>(reader, C13CoffSymbolRva.class, true, TaskMonitor.DUMMY);
C13SectionIterator<CoffSymbolRvaC13Section> iterator =
new C13SectionIterator<>(reader, CoffSymbolRvaC13Section.class, true,
TaskMonitor.DUMMY);
while (iterator.hasNext()) {
C13Section c13Section = iterator.next();
c13Section.dump(writer, TaskMonitor.DUMMY);
}
//@formatter:off
assertEquals(
"C13CoffSymbolRva--------------------------------------------\n" +
"CoffSymbolRvaC13Section-------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 00\n" +
"End C13CoffSymbolRva----------------------------------------\n" +
"C13CoffSymbolRva--------------------------------------------\n" +
"End CoffSymbolRvaC13Section---------------------------------\n" +
"CoffSymbolRvaC13Section-------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 11 11\n" +
"End C13CoffSymbolRva----------------------------------------\n" +
"C13CoffSymbolRva--------------------------------------------\n" +
"End CoffSymbolRvaC13Section---------------------------------\n" +
"CoffSymbolRvaC13Section-------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 1\n" +
"index: 0\n" +
"first: 0\n" +
"last: 1\n" +
"000000 22\n" +
"End C13CoffSymbolRva----------------------------------------\n" +
"C13CoffSymbolRva--------------------------------------------\n" +
"End CoffSymbolRvaC13Section---------------------------------\n" +
"CoffSymbolRvaC13Section-------------------------------------\n" +
"***NOT IMPLEMENTED*** Bytes follow...\n" +
"limit: 2\n" +
"index: 0\n" +
"first: 0\n" +
"last: 2\n" +
"000000 33 33\n" +
"End C13CoffSymbolRva----------------------------------------\n",
"End CoffSymbolRvaC13Section---------------------------------\n",
writer.toString());
//@formatter:on
}