From 45f0ca63fadd064f7571b349efc7a99cc8e0c4b2 Mon Sep 17 00:00:00 2001 From: ghizard <50744617+ghizard@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:42:48 +0000 Subject: [PATCH] GP-4746 - PdbReader dump methods - output NameTable stream records; modify more dumps to use Writer instead of StringBuilder --- .../format/pdb2/pdbreader/AbstractPdb.java | 57 ++++++------ .../pdbreader/AbstractSymbolInformation.java | 62 ++++++------- .../bin/format/pdb2/pdbreader/C11Lines.java | 39 ++++---- .../format/pdb2/pdbreader/DebugHeader.java | 34 ++++--- .../pdbreader/GlobalSymbolInformation.java | 12 +-- .../pdb2/pdbreader/ImageFunctionEntry.java | 30 +++--- .../pdb2/pdbreader/LinkerUnwindInfo.java | 35 ++++--- .../bin/format/pdb2/pdbreader/Module.java | 2 +- .../pdb2/pdbreader/ModuleInformation.java | 65 ++++++------- .../pdb2/pdbreader/ModuleInformation500.java | 7 +- .../pdb2/pdbreader/ModuleInformation600.java | 13 ++- .../bin/format/pdb2/pdbreader/NameTable.java | 79 +++++++++------- .../bin/format/pdb2/pdbreader/Pdb200.java | 4 +- .../bin/format/pdb2/pdbreader/Pdb400.java | 10 +- .../bin/format/pdb2/pdbreader/Pdb700.java | 31 ++----- .../format/pdb2/pdbreader/PdbDebugInfo.java | 6 +- .../pdbreader/PublicSymbolInformation.java | 93 +++++++++---------- .../pdb2/pdbreader/RvaVaDebugHeader.java | 23 ++--- .../pdb2/pdbreader/SectionContribution.java | 29 ++++-- .../pdbreader/SectionContribution1400.java | 31 +++---- .../pdbreader/SectionContribution200.java | 20 ++-- .../pdbreader/SectionContribution400.java | 22 ++--- .../pdbreader/SectionContribution600.java | 28 +++--- .../pdb2/pdbreader/SegmentMapDescription.java | 49 +++++----- .../pdb2/pdbreader/TypeProgramInterface.java | 45 ++++----- .../pdbreader/TypeProgramInterface800.java | 21 ++--- 26 files changed, 404 insertions(+), 443 deletions(-) diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractPdb.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractPdb.java index faeed3eb9b..71606f0330 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractPdb.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractPdb.java @@ -627,8 +627,9 @@ public abstract class AbstractPdb implements AutoCloseable { * debugging only. * @param writer {@link Writer}. * @throws IOException on issue writing to the {@link Writer}. + * @throws CancelledException upon user cancellation */ - public abstract void dumpDirectory(Writer writer) throws IOException; + public abstract void dumpDirectory(Writer writer) throws IOException, CancelledException; //============================================================================================== // Internal Data Methods @@ -658,19 +659,17 @@ public abstract class AbstractPdb implements AutoCloseable { } /** - * Dumps the Version Signature and Age. This package-protected method is for debugging only - * @return {@link String} of pretty output + * Dumps the Version Signature and Age to Writer. This package-protected method is for + * debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - protected String dumpVersionSignatureAge() { - StringBuilder builder = new StringBuilder(); - builder.append("DirectoryHeader---------------------------------------------"); - builder.append("\nversionNumber: "); - builder.append(versionNumber); - builder.append("\nsignature: "); - builder.append(Integer.toHexString(signature)); - builder.append("\nage: "); - builder.append(pdbAge); - return builder.toString(); + protected void dumpVersionSignatureAge(Writer writer) throws IOException { + writer.write("DirectoryHeader---------------------------------------------"); + writer.write("\nversionNumber: " + versionNumber); + writer.write("\nsignature: " + Integer.toHexString(signature)); + writer.write("\nage: " + pdbAge); + writer.write("End DirectoryHeader-----------------------------------------"); } /** @@ -709,27 +708,25 @@ public abstract class AbstractPdb implements AutoCloseable { } /** - * Dumps the Parameters to a {@link String}. This package-protected method is for - * debugging only - * @return {@link String} of pretty output + * Dumps the Parameters to Writer. This package-protected method is for debugging only + * @param writer the writer + * @param monitor the task monitor + * @throws IOException on issue writing to the {@link Writer} + * @throws CancelledException upon user cancellation */ - protected String dumpParameters() { - StringBuilder builder = new StringBuilder(); - builder.append(nameTable.dump()); - builder.append("\nParameters--------------------------------------------------\n"); + protected void dumpParameters(Writer writer, TaskMonitor monitor) + throws IOException, CancelledException { + nameTable.dump(writer, monitor); + writer.write("\nParameters--------------------------------------------------\n"); for (int i = 0; i < parameters.size(); i++) { - builder.append(String.format("parameter[%d]: 0x%08x %d\n", i, parameters.get(i), + writer.write(String.format("parameter[%d]: 0x%08x %d\n", i, parameters.get(i), parameters.get(i))); } - builder.append("Booleans----------------------------------------------------"); - builder.append("\nminimalDebugInfo: "); - builder.append(minimalDebugInfo); - builder.append("\nnoTypeMerge: "); - builder.append(noTypeMerge); - builder.append("\nhasIdStream: "); - builder.append(hasIdStream); - builder.append("\n"); - return builder.toString(); + writer.write("Booleans----------------------------------------------------"); + writer.write("\nminimalDebugInfo: " + minimalDebugInfo); + writer.write("\nnoTypeMerge: " + noTypeMerge); + writer.write("\nhasIdStream: " + hasIdStream); + writer.write("\n"); } /** diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractSymbolInformation.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractSymbolInformation.java index b01e5164b1..38f331b3b9 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractSymbolInformation.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/AbstractSymbolInformation.java @@ -170,43 +170,38 @@ public abstract class AbstractSymbolInformation { void dump(Writer writer) throws IOException, CancelledException, PdbException { StringBuilder builder = new StringBuilder(); builder.append("AbstractSymbolInformation-----------------------------------\n"); - dumpHashHeader(builder); - dumpHashBasics(builder); - dumpHashRecords(builder); + dumpHashHeader(writer); + dumpHashBasics(writer); + dumpHashRecords(writer); builder.append("\nEnd AbstractSymbolInformation-------------------------------\n"); writer.write(builder.toString()); } /** * Debug method for dumping basic information from this {@link AbstractSymbolInformation} - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - protected void dumpHashBasics(StringBuilder builder) { - builder.append("HashBasics--------------------------------------------------\n"); - builder.append("hashRecordsBitMapLength: "); - builder.append(hashRecordsBitMapLength); - builder.append("\nnumExtraBytes: "); - builder.append(numExtraBytes); - builder.append("\nnumHashRecords: "); - builder.append(numHashRecords); - builder.append("\nEnd HashBasics----------------------------------------------\n"); + protected void dumpHashBasics(Writer writer) throws IOException { + writer.write("HashBasics--------------------------------------------------\n"); + writer.write("hashRecordsBitMapLength: " + hashRecordsBitMapLength); + writer.write("\nnumExtraBytes: " + numExtraBytes); + writer.write("\nnumHashRecords: " + numHashRecords); + writer.write("\nEnd HashBasics----------------------------------------------\n"); } - /** + /**builder.append * Debug method for dumping information from this {@link AbstractSymbolInformation} header - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - protected void dumpHashHeader(StringBuilder builder) { - builder.append("HashHeader--------------------------------------------------\n"); - builder.append("headerSignature: "); - builder.append(headerSignature); - builder.append("\nversionNumber: "); - builder.append(versionNumber); - builder.append("\nlengthHashRecords: "); - builder.append(hashRecordsLength); - builder.append("\nlengthBuckets: "); - builder.append(bucketsLength); - builder.append("\nEnd HashHeader----------------------------------------------\n"); + protected void dumpHashHeader(Writer writer) throws IOException { + writer.write("HashHeader--------------------------------------------------\n"); + writer.write("headerSignature: " + headerSignature); + writer.write("\nversionNumber: " + versionNumber); + writer.write("\nlengthHashRecords: " + hashRecordsLength); + writer.write("\nlengthBuckets: " + bucketsLength); + writer.write("\nEnd HashHeader----------------------------------------------\n"); } /** @@ -232,21 +227,22 @@ public abstract class AbstractSymbolInformation { /** * Debug method for dumping hash records from this {@link AbstractSymbolInformation} - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer + * @throws IOException upon issue with writing to the writer * @throws PdbException upon not enough data left to parse * @throws CancelledException upon user cancellation */ - protected void dumpHashRecords(StringBuilder builder) - throws CancelledException, PdbException { + protected void dumpHashRecords(Writer writer) + throws IOException, CancelledException, PdbException { Set hashRecords = getHashRecords(); - builder.append("HashRecords-------------------------------------------------\n"); - builder.append("numHashRecords: " + hashRecords.size() + "\n"); + writer.write("HashRecords-------------------------------------------------\n"); + writer.write("numHashRecords: " + hashRecords.size() + "\n"); for (SymbolHashRecord record : hashRecords) { pdb.checkCancelled(); - builder.append( + writer.write( String.format("0X%08X 0X%04X\n", record.getOffset(), record.getReferenceCount())); } - builder.append("\nEnd HashRecords---------------------------------------------\n"); + writer.write("\nEnd HashRecords---------------------------------------------\n"); } protected void deserializeHashHeader() throws PdbException, CancelledException, IOException { diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/C11Lines.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/C11Lines.java index 350460796f..2c68affe99 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/C11Lines.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/C11Lines.java @@ -15,10 +15,13 @@ */ 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; /** * C11Lines information. As best as we know, only one of C11Lines or C13Lines can be found after @@ -250,41 +253,38 @@ public class C11Lines { @Override public String toString() { - try { - return dump(); - } - catch (CancelledException e) { - return ""; - } + return String.format("%s: numFiles = %d, numSegs = %d", getClass().getSimpleName(), cFile, + cSeg); } /** - * Dumps this class. This package-protected method is for debugging only. - * @return the {@link String} output. + * Dumps this class to Writer. This package-protected method is for debugging only + * @param writer the writer + * @param monitor the task monitor * @throws CancelledException upon user cancellation + * @throws IOException upon issue writing to writer */ - String dump() throws CancelledException { - StringBuilder builder = new StringBuilder(); - builder.append("Lines-------------------------------------------------------\n"); - builder.append("cFile: " + cFile + " cSeg: " + cSeg + "\n"); + void dump(Writer writer, TaskMonitor monitor) throws CancelledException, IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write("cFile: " + cFile + " cSeg: " + cSeg + "\n"); for (int i = 0; i < cFile; i++) { pdb.checkCancelled(); - builder.append("baseSrcFile[" + i + "]: " + baseSrcFile.get(i) + "\n"); + writer.write("baseSrcFile[" + i + "]: " + baseSrcFile.get(i) + "\n"); } for (int i = 0; i < cSeg; i++) { pdb.checkCancelled(); - builder.append(i + ": start:" + startEnd.get(i).getStart() + " end: " + + writer.write(i + ": start:" + startEnd.get(i).getStart() + " end: " + startEnd.get(i).getEnd() + " seg: " + seg.get(i) + "\n"); } for (int i = 0; i < cFile; i++) { pdb.checkCancelled(); - builder.append( + writer.write( " file[" + i + "]: cSeg: " + ccSegs.get(i) + " name: " + names.get(i) + "\n"); List myBaseSrcLn = baseSrcLines.get(i); List myStartEnds = startEnds.get(i); for (int j = 0; j < ccSegs.get(i); j++) { C11LinesStartEnd se = myStartEnds.get(j); - builder.append(" " + j + ": baseSrcLn: " + myBaseSrcLn.get(j) + " start: " + + writer.write(" " + j + ": baseSrcLn: " + myBaseSrcLn.get(j) + " start: " + se.getStart() + " end: " + se.getEnd() + "\n"); } List segNums = segmentNumbers.get(i); @@ -294,15 +294,14 @@ public class C11Lines { pdb.checkCancelled(); List segOffsets = fileSegOffsets.get(j); List segLineNums = fileSegLineNums.get(j); - builder.append(" seg[" + j + "]: Seg: " + segNums.get(j) + " cPair: " + + writer.write(" seg[" + j + "]: Seg: " + segNums.get(j) + " cPair: " + segOffsets.size() + "\n"); for (int k = 0; k < segOffsets.size(); k++) { - builder.append(" " + segLineNums.get(k) + ":" + segOffsets.get(k) + "\n"); + writer.write(" " + segLineNums.get(k) + ":" + segOffsets.get(k) + "\n"); } } } - builder.append("End Lines---------------------------------------------------\n"); - return builder.toString(); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/DebugHeader.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/DebugHeader.java index e0fee9fdf2..2cc374e1d6 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/DebugHeader.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/DebugHeader.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.*; + /** * Debug header for various, yet-to-be-determined debug structures. {@link RvaVaDebugHeader}, an * extension of this class, is used for PData and XData within {@link DebugData}. @@ -62,25 +64,31 @@ public class DebugHeader { @Override public String toString() { - return dump(); + StringWriter writer = new StringWriter(); + try { + dump(writer); + return writer.toString(); + } + catch (IOException e) { + return "Issue in " + getClass().getSimpleName() + " toString(): " + e.getMessage(); + } } /** - * Dumps this class. This package-protected method is for debugging only. - * @return the {@link String} output. + * Dumps this class to Writer. This package-protected method is for debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("DebugHeader-------------------------------------------------\n"); - dumpInternal(builder); - builder.append("End DebugHeader---------------------------------------------\n"); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + dumpInternal(writer); + PdbReaderUtils.dumpTail(writer, this); } - protected void dumpInternal(StringBuilder builder) { - builder.append(String.format("headerVersion: 0X%08X\n", headerVersion)); - builder.append(String.format("headerLength: 0X%08X\n", headerLength)); - builder.append(String.format("dataLength: 0X%08X\n", dataLength)); + protected void dumpInternal(Writer writer) throws IOException { + writer.write(String.format("headerVersion: 0X%08X\n", headerVersion)); + writer.write(String.format("headerLength: 0X%08X\n", headerLength)); + writer.write(String.format("dataLength: 0X%08X\n", dataLength)); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/GlobalSymbolInformation.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/GlobalSymbolInformation.java index db0e990298..36ff653da2 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/GlobalSymbolInformation.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/GlobalSymbolInformation.java @@ -71,13 +71,11 @@ public class GlobalSymbolInformation extends AbstractSymbolInformation { */ @Override void dump(Writer writer) throws IOException, CancelledException, PdbException { - StringBuilder builder = new StringBuilder(); - builder.append("GlobalSymbolInformation-------------------------------------\n"); - dumpHashHeader(builder); - dumpHashBasics(builder); - dumpHashRecords(builder); - builder.append("\nEnd GlobalSymbolInformation---------------------------------\n"); - writer.write(builder.toString()); + writer.write("GlobalSymbolInformation-------------------------------------\n"); + dumpHashHeader(writer); + dumpHashBasics(writer); + dumpHashRecords(writer); + writer.write("\nEnd GlobalSymbolInformation---------------------------------\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ImageFunctionEntry.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ImageFunctionEntry.java index d398991a6c..cc3834a3b6 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ImageFunctionEntry.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ImageFunctionEntry.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.*; + /** * Image Function Entry data seems to be the main data PData record of the {@link DebugData}. */ @@ -61,21 +63,27 @@ public class ImageFunctionEntry { @Override public String toString() { - return dump(); + StringWriter writer = new StringWriter(); + try { + dump(writer); + return writer.toString(); + } + catch (IOException e) { + return "Issue in " + getClass().getSimpleName() + " toString(): " + e.getMessage(); + } } /** - * Dumps this class. This package-protected method is for debugging only. - * @return the {@link String} output. + * Dumps this class to Writer. This package-protected method is for debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("ImageFunctionEntry------------------------------------------\n"); - builder.append(String.format("startingAddress: 0X%08X\n", startingAddress)); - builder.append(String.format("endingAddress: 0X%08X\n", endingAddress)); - builder.append(String.format("endOfPrologueAddress: 0X%08X\n", endOfPrologueAddress)); - builder.append("End ImageFunctionEntry--------------------------------------\n"); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write(String.format("startingAddress: 0X%08X\n", startingAddress)); + writer.write(String.format("endingAddress: 0X%08X\n", endingAddress)); + writer.write(String.format("endOfPrologueAddress: 0X%08X\n", endOfPrologueAddress)); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/LinkerUnwindInfo.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/LinkerUnwindInfo.java index 1dcdbaebef..b73f34e61b 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/LinkerUnwindInfo.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/LinkerUnwindInfo.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.*; + /** * Linker Unwind Information that seems to be used in some XData types within {@link DebugData}. */ @@ -61,24 +63,31 @@ public class LinkerUnwindInfo { @Override public String toString() { - return dump(); + StringWriter writer = new StringWriter(); + try { + dump(writer); + return writer.toString(); + } + catch (IOException e) { + return "Issue in " + getClass().getSimpleName() + " toString(): " + e.getMessage(); + } } /** - * Dumps this class. This package-protected method is for debugging only. - * @return the {@link String} output. + * Dumps this class to Writer. This package-protected method is for debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("LinkerUnwindInfo--------------------------------------------\n"); - dumpInternal(builder); - builder.append("End LinkerUnwindInfo----------------------------------------\n"); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + dumpInternal(writer); + PdbReaderUtils.dumpTail(writer, this); } - protected void dumpInternal(StringBuilder builder) { - builder.append(String.format("version: 0X%04X\n", version)); - builder.append(String.format("flags: 0X%04X\n", flags)); - builder.append(String.format("dataLength: 0X%08X\n", dataLength)); + protected void dumpInternal(Writer writer) throws IOException { + writer.write(String.format("version: 0X%04X\n", version)); + writer.write(String.format("flags: 0X%04X\n", flags)); + writer.write(String.format("dataLength: 0X%08X\n", dataLength)); } + } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Module.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Module.java index a26365e166..4969689b6b 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Module.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Module.java @@ -345,7 +345,7 @@ public class Module { writer.write("C11Lines----------------------------------------------------\n"); C11Lines c11lines = getLineInformation(); if (c11lines != null) { - writer.write(c11lines.dump()); + c11lines.dump(writer, pdb.getMonitor()); } writer.write("End C11Lines------------------------------------------------\n"); } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation.java index 06042fe93e..d8e6e46db0 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; import java.util.*; /** @@ -193,10 +195,11 @@ public abstract class ModuleInformation { protected abstract void parseAdditionals(PdbByteReader reader) throws PdbException; /** - * Dumps the Additionals. This method is for debugging only - * @return {@link String} of pretty output + * Dumps the Additionals to Writer. This method is for debugging only + * @param writer the writer + * @throws IOException upon issues writing to the writer */ - protected abstract String dumpAdditionals(); + protected abstract void dumpAdditionals(Writer writer) throws IOException; //============================================================================================== // Package-Protected Internals @@ -211,46 +214,34 @@ public abstract class ModuleInformation { } /** - * Dumps this module. This method is for debugging only - * @return {@link String} of pretty output + * Dumps this module to the Writer. This method is for debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("ModuleInformation-------------------------------------------\n"); - builder.append("modulePointer: "); - builder.append(modulePointer); - builder.append("\n"); - builder.append(sectionContribution.dump()); - builder.append("\nwrittenSinceOpen: "); - builder.append(writtenSinceOpen); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write("modulePointer: " + modulePointer); + writer.write("\n"); + sectionContribution.dump(writer); + writer.write("\nwrittenSinceOpen: " + writtenSinceOpen); - builder.append("\necSymbolicInformationEnabled: "); - builder.append(ecSymbolicInformationEnabled); + writer.write("\necSymbolicInformationEnabled: " + ecSymbolicInformationEnabled); - builder.append("\nspare: "); - builder.append(spare); - builder.append("\nindexToTSMList: "); - builder.append(indexToTSMList); - builder.append("\nstreamNumberDebugInformation: "); - builder.append(streamNumberDebugInformation); - builder.append("\nsizeLocalSymbolsDebugInformation: "); - builder.append(sizeLocalSymbolsDebugInformation); - builder.append("\nsizeLineNumberDebugInformation: "); - builder.append(sizeLineNumberDebugInformation); - builder.append("\nsizeC13StyleLineNumberInformation: "); - builder.append(sizeC13StyleLineNumberInformation); - builder.append("\nnumFilesContributing: "); - builder.append(numFilesContributing); + writer.write("\nspare: " + spare); + writer.write("\nindexToTSMList: " + indexToTSMList); + writer.write("\nstreamNumberDebugInformation: " + streamNumberDebugInformation); + writer.write("\nsizeLocalSymbolsDebugInformation: " + sizeLocalSymbolsDebugInformation); + writer.write("\nsizeLineNumberDebugInformation: " + sizeLineNumberDebugInformation); + writer.write("\nsizeC13StyleLineNumberInformation: " + sizeC13StyleLineNumberInformation); + writer.write("\nnumFilesContributing: " + numFilesContributing); - builder.append(dumpAdditionals()); + dumpAdditionals(writer); - builder.append("\nmoduleName: "); - builder.append(moduleName); - builder.append("\nobjectFileName: "); - builder.append(objectFileName); + writer.write("\nmoduleName: " + moduleName); + writer.write("\nobjectFileName: " + objectFileName); + writer.write("\n"); - builder.append("\nEnd ModuleInformation---------------------------------------\n"); - return builder.toString(); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation500.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation500.java index 206bde5824..2708b8b666 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation500.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation500.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link ModuleInformation} for Microsoft v5.00 PDB. */ @@ -43,8 +46,8 @@ public class ModuleInformation500 extends ModuleInformation { } @Override - protected String dumpAdditionals() { - return ""; + protected void dumpAdditionals(Writer writer) throws IOException { + // do nothing } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation600.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation600.java index 973f88dab8..bb5e14f567 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation600.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/ModuleInformation600.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link ModuleInformation} for Microsoft v6.00 PDB. */ @@ -44,13 +47,9 @@ public class ModuleInformation600 extends ModuleInformation { } @Override - protected String dumpAdditionals() { - StringBuilder builder = new StringBuilder(); - builder.append("\nnameIndexSourceFile: "); - builder.append(nameIndexSourceFile); - builder.append("\nnameIndexCompilerPdbPath: "); - builder.append(nameIndexCompilerPdbPath); - return builder.toString(); + protected void dumpAdditionals(Writer writer) throws IOException { + writer.write("\nnameIndexSourceFile: " + nameIndexSourceFile); + writer.write("\nnameIndexCompilerPdbPath: " + nameIndexCompilerPdbPath); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/NameTable.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/NameTable.java index 1ccb9ecdb7..619f4e6bff 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/NameTable.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/NameTable.java @@ -16,9 +16,11 @@ package ghidra.app.util.bin.format.pdb2.pdbreader; import java.io.IOException; +import java.io.Writer; import java.util.*; import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; /** * This class represents Name Table component of a PDB file. This class is only @@ -231,66 +233,73 @@ public class NameTable { /** * Dumps the Name Table. This method is for debugging only. - * @return {@link String} of pretty output. + * @param writer the writer to which to write the dump + * @param monitor the task monitor + * @throws CancelledException upon user cancellation + * @throws IOException upon issue writing to writer */ - protected String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("NameTable---------------------------------------------------"); - builder.append("\nnameBufferSize: "); - builder.append(nameBufferSize); - builder.append("\nnumPairs: "); - builder.append(numPairs); - builder.append("\ndomainSize: "); - builder.append(domainSize); - builder.append("\nmaxPossiblePresent: "); - builder.append(presentList.getMaxPossible()); - builder.append("\nPresent: {"); + void dump(Writer writer, TaskMonitor monitor) throws CancelledException, IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write("\nnameBufferSize: " + nameBufferSize); + writer.write("\nnumPairs: " + numPairs); + writer.write("\ndomainSize: " + domainSize); + writer.write("\nmaxPossiblePresent: " + presentList.getMaxPossible()); + writer.write("\nPresent: {"); boolean firstSeen = false; for (int i = 0; i < presentList.getMaxPossible(); i++) { if (presentList.contains(i)) { if (firstSeen) { - builder.append(", "); + writer.write(", "); } else { firstSeen = true; } - builder.append(i); + writer.write("" + i); } } - builder.append("}"); - builder.append("\nmaxPossibleDeleted: "); - builder.append(deletedList.getMaxPossible()); - builder.append("\nDeleted: {"); + writer.write("}"); + writer.write("\nmaxPossibleDeleted: " + deletedList.getMaxPossible()); + writer.write("\nDeleted: {"); firstSeen = false; for (int i = 0; i < deletedList.getMaxPossible(); i++) { if (deletedList.contains(i)) { if (firstSeen) { - builder.append(", "); + writer.write(", "); } else { firstSeen = true; } - builder.append(i); + writer.write("" + i); } } - builder.append("}\n"); - builder.append("------------------------------------------------------------\n"); + writer.write("}\n"); + writer.write("------------------------------------------------------------\n"); for (String name : streamNumbersByName.keySet()) { - builder.append(name); - builder.append(" : "); - builder.append(streamNumbersByName.get(name)); - builder.append("\n"); + writer.write(name + " : " + streamNumbersByName.get(name) + "\n"); } - builder.append("------------------------------------------------------------\n"); + writer.write("------------------------------------------------------------\n"); for (int streamNumber : namesByStreamNumber.keySet()) { - builder.append(streamNumber); - builder.append(" : "); - builder.append(namesByStreamNumber.get(streamNumber)); - builder.append("\n"); + writer.write(streamNumber + " : " + namesByStreamNumber.get(streamNumber) + "\n"); + } + dumpMapTables(writer, monitor); + PdbReaderUtils.dumpTail(writer, this); + } + + private void dumpMapTables(Writer writer, TaskMonitor monitor) + throws CancelledException, IOException { + for (int streamNumber : streamNumbers) { + pdb.checkCancelled(); + writer.write("StreamNameTable---------------------------------------------\n"); + writer.write("streamNumber: " + streamNumber + "\n"); + Map stringsByOffset = stringTablesByStreamNumber.get(streamNumber); + ArrayList sortedKeys = new ArrayList<>(stringsByOffset.keySet()); + Collections.sort(sortedKeys); + for (int offset : sortedKeys) { + String str = stringsByOffset.get(offset); + writer.write(offset + ": " + str + "\n"); + } + writer.write("End StreamNameTable-----------------------------------------\n"); } - // TODO: output map entries for each table. - builder.append("End NameTable-----------------------------------------------\n"); - return builder.toString(); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb200.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb200.java index 597e84ab90..0f2dc3e6e5 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb200.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb200.java @@ -60,9 +60,7 @@ public class Pdb200 extends AbstractPdb { @Override public void dumpDirectory(Writer writer) throws IOException { - StringBuilder builder = new StringBuilder(); - builder.append(dumpVersionSignatureAge()); - writer.write(builder.toString()); + dumpVersionSignatureAge(writer); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb400.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb400.java index b975d608bf..c99304da0d 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb400.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb400.java @@ -60,12 +60,10 @@ public class Pdb400 extends AbstractPdb { } @Override - public void dumpDirectory(Writer writer) throws IOException { - StringBuilder builder = new StringBuilder(); - builder.append(dumpVersionSignatureAge()); - builder.append("\n"); - builder.append(dumpParameters()); - writer.write(builder.toString()); + public void dumpDirectory(Writer writer) throws IOException, CancelledException { + dumpVersionSignatureAge(writer); + writer.write("\n"); + dumpParameters(writer, getMonitor()); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb700.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb700.java index c452da48ac..eec03a1f1d 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb700.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/Pdb700.java @@ -61,31 +61,14 @@ public class Pdb700 extends AbstractPdb { } @Override - public void dumpDirectory(Writer writer) throws IOException { - StringBuilder builder = new StringBuilder(); - builder.append(dumpVersionSignatureAge()); - builder.append("\n"); - builder.append(dumpGUID()); - builder.append("\n"); - builder.append(dumpParameters()); - writer.write(builder.toString()); - } - - //============================================================================================== - // Internal Data Methods - //============================================================================================== - /** - * Dumps the GUID. This method is for debugging only - * @return {@link String} of pretty output - */ - protected String dumpGUID() { - if (guid == null) { - return ""; + public void dumpDirectory(Writer writer) throws IOException, CancelledException { + dumpVersionSignatureAge(writer); + writer.write("\n"); + if (guid != null) { + writer.write("GUID: " + guid); + writer.write("\n"); } - StringBuilder builder = new StringBuilder(); - builder.append("GUID: "); - builder.append(guid); - return builder.toString(); + dumpParameters(writer, getMonitor()); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbDebugInfo.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbDebugInfo.java index 0f2a0ffa30..7ebc5bd0bc 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbDebugInfo.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbDebugInfo.java @@ -516,7 +516,7 @@ public abstract class PdbDebugInfo { protected void dumpModuleInformation(Writer writer) throws IOException, CancelledException { for (ModuleInformation information : moduleInformationList) { pdb.checkCancelled(); - writer.write(information.dump()); + information.dump(writer); writer.write("\n"); } } @@ -531,7 +531,7 @@ public abstract class PdbDebugInfo { protected void dumpSectionContributions(Writer writer) throws IOException, CancelledException { for (SectionContribution contribution : sectionContributionList) { pdb.checkCancelled(); - writer.write(contribution.dump()); + contribution.dump(writer); writer.write("\n"); } } @@ -546,7 +546,7 @@ public abstract class PdbDebugInfo { protected void dumpSegmentMap(Writer writer) throws IOException, CancelledException { for (SegmentMapDescription description : segmentMapList) { pdb.checkCancelled(); - writer.write(description.dump()); + description.dump(writer); writer.write("\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PublicSymbolInformation.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PublicSymbolInformation.java index 6af0e4b76b..56799fa7bd 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PublicSymbolInformation.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PublicSymbolInformation.java @@ -203,19 +203,18 @@ public class PublicSymbolInformation extends AbstractSymbolInformation { */ @Override void dump(Writer writer) throws IOException, CancelledException, PdbException { - StringBuilder builder = new StringBuilder(); - builder.append("PublicSymbolInformation-------------------------------------\n"); - dumpPubHeader(builder); - dumpHashHeader(builder); - dumpHashBasics(builder); - dumpHashRecords(builder); + PdbReaderUtils.dumpHead(writer, this); + dumpPubHeader(writer); + dumpHashHeader(writer); + dumpHashBasics(writer); + dumpHashRecords(writer); - dumpAddressMap(builder); - dumpThunkMap(builder); - dumpSectionMap(builder); + dumpAddressMap(writer); + dumpThunkMap(writer); + dumpSectionMap(writer); + writer.write("\n"); - builder.append("\nEnd PublicSymbolInformation---------------------------------\n"); - writer.write(builder.toString()); + PdbReaderUtils.dumpTail(writer, this); } //============================================================================================== @@ -239,23 +238,23 @@ public class PublicSymbolInformation extends AbstractSymbolInformation { /** * Debug method for dumping Address Map information from this {@link AbstractSymbolInformation} - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer * @throws IOException on file seek or read, invalid parameters, bad file configuration, or * inability to read required bytes * @throws PdbException upon not enough data left to parse * @throws CancelledException upon user cancellation */ - private void dumpAddressMap(StringBuilder builder) + private void dumpAddressMap(Writer writer) throws CancelledException, IOException, PdbException { - builder.append("AddressMapSymbolOffsets-------------------------------------\n"); + writer.write("AddressMapSymbolOffsets-------------------------------------\n"); List myAddressMapSymbolOffsets = getAddressMapSymbolOffsets(); - builder.append("numAddressMapSymbolOffsets: " + myAddressMapSymbolOffsets.size() + "\n"); + writer.write("numAddressMapSymbolOffsets: " + myAddressMapSymbolOffsets.size() + "\n"); int num = 0; for (Long val : myAddressMapSymbolOffsets) { pdb.checkCancelled(); - builder.append(String.format("0X%08X: 0X%012X\n", num++, val)); + writer.write(String.format("0X%08X: 0X%012X\n", num++, val)); } - builder.append("\nEnd AddressMapSymbolOffsets---------------------------------\n"); + writer.write("\nEnd AddressMapSymbolOffsets---------------------------------\n"); } /** @@ -279,24 +278,24 @@ public class PublicSymbolInformation extends AbstractSymbolInformation { /** * Debug method for dumping Thunk Map information from this {@link AbstractSymbolInformation} - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer * @throws IOException on file seek or read, invalid parameters, bad file configuration, or * inability to read required bytes * @throws PdbException upon not enough data left to parse * @throws CancelledException upon user cancellation */ - private void dumpThunkMap(StringBuilder builder) + private void dumpThunkMap(Writer writer) throws CancelledException, IOException, PdbException { Map myThunkTargetOffsetsByTableOffset = getThunkTargetOffsetsByTableOffset(); - builder.append("ThunkMap----------------------------------------------------\n"); - builder.append("numThunkTargetOffsetsByTableOffset: " + + writer.write("ThunkMap----------------------------------------------------\n"); + writer.write("numThunkTargetOffsetsByTableOffset: " + myThunkTargetOffsetsByTableOffset.size() + "\n"); for (Map.Entry entry : myThunkTargetOffsetsByTableOffset.entrySet()) { pdb.checkCancelled(); - builder.append(String.format("0X%08X 0X%08X\n", entry.getKey(), entry.getValue())); + writer.write(String.format("0X%08X 0X%08X\n", entry.getKey(), entry.getValue())); } - builder.append("\nEnd ThunkMap------------------------------------------------\n"); + writer.write("\nEnd ThunkMap------------------------------------------------\n"); } /** @@ -320,51 +319,43 @@ public class PublicSymbolInformation extends AbstractSymbolInformation { /** * Debug method for dumping Section Map information from this {@link AbstractSymbolInformation} - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer * @throws IOException on file seek or read, invalid parameters, bad file configuration, or * inability to read required bytes * @throws PdbException upon not enough data left to parse * @throws CancelledException upon user cancellation */ - private void dumpSectionMap(StringBuilder builder) + private void dumpSectionMap(Writer writer) throws CancelledException, IOException, PdbException { Map myAbsoluteOffsetsBySectionNumber = getAbsoluteOffsetsBySectionNumber(); - builder.append("SectionMap--------------------------------------------------\n"); - builder.append( + writer.write("SectionMap--------------------------------------------------\n"); + writer.write( "numAbsoluteOffsetsBySectionNumber: " + myAbsoluteOffsetsBySectionNumber.size() + "\n"); for (Map.Entry entry : myAbsoluteOffsetsBySectionNumber.entrySet()) { pdb.checkCancelled(); - builder.append(String.format("0X%08X 0X%08X\n", entry.getKey(), entry.getValue())); + writer.write(String.format("0X%08X 0X%08X\n", entry.getKey(), entry.getValue())); } - builder.append("\nEnd SectionMap----------------------------------------------\n"); + writer.write("\nEnd SectionMap----------------------------------------------\n"); } /** * Debug method for dumping the {@link PublicSymbolInformation} header - * @param builder {@link StringBuilder} to which to dump the information + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - private void dumpPubHeader(StringBuilder builder) { - builder.append("PublicSymbolInformationHeader-------------------------------\n"); - builder.append("symbolHashLength: "); - builder.append(symbolHashLength); - builder.append("\naddressMapLength: "); - builder.append(addressMapLength); - builder.append("\nnumThunks: "); - builder.append(numThunks); - builder.append("\nthunkSize: "); - builder.append(thunkSize); - builder.append("\niSectionThunkTable: "); - builder.append(iSectionThunkTable); - builder.append("\noffsetThunkTable: "); - builder.append(offsetThunkTable); - builder.append("\nnumSections: "); - builder.append(numSections); - builder.append("\nthunkMapLength: "); - builder.append(thunkMapLength); - builder.append("\nthunkTableLength: "); - builder.append(thunkTableLength); - builder.append("\nEnd PublicSymbolInformationHeader---------------------------\n"); + private void dumpPubHeader(Writer writer) throws IOException { + writer.write("PublicSymbolInformationHeader-------------------------------\n"); + writer.write("symbolHashLength: " + symbolHashLength); + writer.write("\naddressMapLength: " + addressMapLength); + writer.write("\nnumThunks: " + numThunks); + writer.write("\nthunkSize: " + thunkSize); + writer.write("\niSectionThunkTable: " + iSectionThunkTable); + writer.write("\noffsetThunkTable: " + offsetThunkTable); + writer.write("\nnumSections: " + numSections); + writer.write("\nthunkMapLength: " + thunkMapLength); + writer.write("\nthunkTableLength: " + thunkTableLength); + writer.write("\nEnd PublicSymbolInformationHeader---------------------------\n"); } void deserializePubHeader() throws PdbException, CancelledException, IOException { diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/RvaVaDebugHeader.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/RvaVaDebugHeader.java index 3dc2809d69..d20a344491 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/RvaVaDebugHeader.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/RvaVaDebugHeader.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; import java.math.BigInteger; /** @@ -75,23 +77,14 @@ public class RvaVaDebugHeader extends DebugHeader { } @Override - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("RvaVaDebugHeader--------------------------------------------\n"); - dumpInternal(builder); - builder.append("End RvaVaDebugHeader----------------------------------------\n"); - return builder.toString(); - } - - @Override - protected void dumpInternal(StringBuilder builder) { - super.dumpInternal(builder); - builder.append(String.format("relativeVirtualAddressDataBase: 0X%08X\n", + protected void dumpInternal(Writer writer) throws IOException { + super.dumpInternal(writer); + writer.write(String.format("relativeVirtualAddressDataBase: 0X%08X\n", relativeVirtualAddressDataBase)); - builder.append( + writer.write( String.format("virtualAddressImageBase: 0X%016X\n", virtualAddressImageBase)); - builder.append(String.format("unsignedIntReserved1: 0X%08X\n", unsignedIntReserved1)); - builder.append(String.format("unsignedIntReserved2: 0X%08X\n", unsignedIntReserved2)); + writer.write(String.format("unsignedIntReserved1: 0X%08X\n", unsignedIntReserved1)); + writer.write(String.format("unsignedIntReserved2: 0X%08X\n", unsignedIntReserved2)); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution.java index 6551fcdd01..b7d487e9c4 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.*; + /** * This class represents Section Contribution component of a PDB file. This class is only * suitable for reading; not for writing or modifying a PDB. @@ -62,7 +64,14 @@ public abstract class SectionContribution { @Override public String toString() { - return dump(); + StringWriter writer = new StringWriter(); + try { + dump(writer); + return writer.toString(); + } + catch (IOException e) { + return "Issue in " + getClass().getSimpleName() + " toString(): " + e.getMessage(); + } } //============================================================================================== @@ -77,23 +86,23 @@ public abstract class SectionContribution { /** * Dumps the SectionContribution. This method is for debugging only - * @return {@link String} of pretty output + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - abstract String dumpInternals(); + abstract void dumpInternals(Writer writer) throws IOException; //============================================================================================== // Package-Protected Internals //============================================================================================== /** * Dumps the Section Contribution. This method is for debugging only - * @return {@link String} of pretty output + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("SectionContribution-----------------------------------------\n"); - builder.append(dumpInternals()); - builder.append("\nEnd SectionContribution-------------------------------------\n"); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + dumpInternals(writer); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution1400.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution1400.java index 244ea32b51..fc3e0ae35d 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution1400.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution1400.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link SectionContribution} for Microsoft v14.00 PDB. */ @@ -38,24 +41,16 @@ public class SectionContribution1400 extends SectionContribution { } @Override - String dumpInternals() { - StringBuilder builder = new StringBuilder(); - builder.append("isect: "); - builder.append(isect); - builder.append("\noffset: "); - builder.append(offset); - builder.append("\nlength: "); - builder.append(length); - builder.append(String.format("\ncharacteristics: 0X%08X", characteristics)); - builder.append("\nimod: "); - builder.append(imod); - builder.append("\ndataCrc: "); - builder.append(dataCrc); - builder.append("\nrelocationCrc: "); - builder.append(relocationCrc); - builder.append("\nunknownSectionContributionField: "); - builder.append(unknownSectionContributionField); - return builder.toString(); + void dumpInternals(Writer writer) throws IOException { + writer.write("isect: " + isect); + writer.write("\noffset: " + offset); + writer.write("\nlength: " + length); + writer.write(String.format("\ncharacteristics: 0X%08X", characteristics)); + writer.write("\nimod: " + imod); + writer.write("\ndataCrc: " + dataCrc); + writer.write("\nrelocationCrc: " + relocationCrc); + writer.write("\nunknownSectionContributionField: " + unknownSectionContributionField); + writer.write("\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution200.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution200.java index c0e1b91105..bdd55b6d7f 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution200.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution200.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link SectionContribution} for Microsoft v2.00 PDB. */ @@ -32,17 +35,12 @@ public class SectionContribution200 extends SectionContribution { } @Override - String dumpInternals() { - StringBuilder builder = new StringBuilder(); - builder.append("isect: "); - builder.append(isect); - builder.append("\noffset: "); - builder.append(offset); - builder.append("\nlength: "); - builder.append(length); - builder.append("\nimod: "); - builder.append(imod); - return builder.toString(); + void dumpInternals(Writer writer) throws IOException { + writer.write("isect: " + isect); + writer.write("\noffset: " + offset); + writer.write("\nlength: " + length); + writer.write("\nimod: " + imod); + writer.write("\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution400.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution400.java index 3a610d5a42..496f1cba25 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution400.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution400.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link SectionContribution} for Microsoft v4.00 PDB. */ @@ -34,18 +37,13 @@ public class SectionContribution400 extends SectionContribution { } @Override - String dumpInternals() { - StringBuilder builder = new StringBuilder(); - builder.append("isect: "); - builder.append(isect); - builder.append("\noffset: "); - builder.append(offset); - builder.append("\nlength: "); - builder.append(length); - builder.append(String.format("\ncharacteristics: 0X%08X", characteristics)); - builder.append("\nimod: "); - builder.append(imod); - return builder.toString(); + void dumpInternals(Writer writer) throws IOException { + writer.write("isect: " + isect); + writer.write("\noffset: " + offset); + writer.write("\nlength: " + length); + writer.write(String.format("\ncharacteristics: 0X%08X", characteristics)); + writer.write("\nimod: " + imod); + writer.write("\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution600.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution600.java index 076cecde97..5a98a614d2 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution600.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SectionContribution600.java @@ -15,6 +15,9 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.IOException; +import java.io.Writer; + /** * This class is the version of {@link SectionContribution} for Microsoft v6.00 PDB. */ @@ -37,22 +40,15 @@ public class SectionContribution600 extends SectionContribution { } @Override - String dumpInternals() { - StringBuilder builder = new StringBuilder(); - builder.append("isect: "); - builder.append(isect); - builder.append("\noffset: "); - builder.append(offset); - builder.append("\nlength: "); - builder.append(length); - builder.append(String.format("\ncharacteristics: 0X%08X", characteristics)); - builder.append("\nimod: "); - builder.append(imod); - builder.append("\ndataCrc: "); - builder.append(dataCrc); - builder.append("\nrelocationCrc: "); - builder.append(relocationCrc); - return builder.toString(); + void dumpInternals(Writer writer) throws IOException { + writer.write("isect: " + isect); + writer.write("\noffset: " + offset); + writer.write("\nlength: " + length); + writer.write(String.format("\ncharacteristics: 0X%08X", characteristics)); + writer.write("\nimod: " + imod); + writer.write("\ndataCrc: " + dataCrc); + writer.write("\nrelocationCrc: " + relocationCrc); + writer.write("\n"); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SegmentMapDescription.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SegmentMapDescription.java index 32d111ded8..c84b04232f 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SegmentMapDescription.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/SegmentMapDescription.java @@ -15,6 +15,8 @@ */ package ghidra.app.util.bin.format.pdb2.pdbreader; +import java.io.*; + /** * This class represents Segment Map Description component of a PDB file. This class is only * suitable for reading; not for writing or modifying a PDB. @@ -123,34 +125,33 @@ public class SegmentMapDescription { @Override public String toString() { - return dump(); + StringWriter writer = new StringWriter(); + try { + dump(writer); + return writer.toString(); + } + catch (IOException e) { + return "Issue in " + getClass().getSimpleName() + " toString(): " + e.getMessage(); + } } /** - * Dumps the {@link SegmentMapDescription}. This method is for debugging only. - * @return {@link String} of pretty output. + * Dumps the {@link SegmentMapDescription} to writer. This method is for debugging only + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - protected String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("SegmentMapDescription---------------------------------------"); - builder.append("\nflags: "); - builder.append(String.format("0x%04x", flags)); - builder.append("\novl: "); - builder.append(ovl); - builder.append("\ngroup: "); - builder.append(group); - builder.append("\nframe: "); - builder.append(frame); - builder.append("\nsegNameIndex: "); - builder.append(segNameIndex); - builder.append("; classNameIndex: "); - builder.append(classNameIndex); - builder.append("; segOffset: "); - builder.append(segOffset); - builder.append("; segLength: "); - builder.append(segLength); - builder.append("\nEnd SegmentMapDescription-----------------------------------\n"); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write(String.format("\nflags: 0x%04x", flags)); + writer.write("\novl: " + ovl); + writer.write("\ngroup: " + group); + writer.write("\nframe: " + frame); + writer.write("\nsegNameIndex: " + segNameIndex); + writer.write("; classNameIndex: " + classNameIndex); + writer.write("; segOffset: " + segOffset); + writer.write("; segLength: " + segLength); + writer.write("\n"); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface.java index 018e6bbb39..f0e6741cd7 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface.java @@ -4,9 +4,9 @@ * 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. @@ -480,32 +480,23 @@ public abstract class TypeProgramInterface implements TPI { /** * Dumps the this {@link TypeProgramInterfaceHash}. This method is for debugging only - * @return {@link String} of pretty output + * @param writer the writer + * @throws IOException upon issue with writing to the writer */ - protected String dump() { - StringBuilder builder = new StringBuilder(); - builder.append("Hash--------------------------------------------------------"); - builder.append("\nhashStreamNumber: "); - builder.append(hashStreamNumber); - builder.append("\nhashStreamNumberAuxiliary: "); - builder.append(hashStreamNumberAuxiliary); - builder.append("\nhashKeySize: "); - builder.append(hashKeySize); - builder.append("\nnumHashBins: "); - builder.append(numHashBins); - builder.append("\noffsetHashVals: "); - builder.append(offsetHashVals); - builder.append("\nlengthHashVals: "); - builder.append(lengthHashVals); - builder.append("\noffsetTypeIndexOffsetPairs: "); - builder.append(offsetTypeIndexOffsetPairs); - builder.append("\nlengthTypeIndexOffsetPairs: "); - builder.append(lengthTypeIndexOffsetPairs); - builder.append("\noffsetHashAdjustment: "); - builder.append(offsetHashAdjustment); - builder.append("\nlengthHashAdjustment: "); - builder.append(lengthHashAdjustment); - return builder.toString(); + void dump(Writer writer) throws IOException { + PdbReaderUtils.dumpHead(writer, this); + writer.write("\nhashStreamNumber: " + hashStreamNumber); + writer.write("\nhashStreamNumberAuxiliary: " + hashStreamNumberAuxiliary); + writer.write("\nhashKeySize: " + hashKeySize); + writer.write("\nnumHashBins: " + numHashBins); + writer.write("\noffsetHashVals: " + offsetHashVals); + writer.write("\nlengthHashVals: " + lengthHashVals); + writer.write("\noffsetTypeIndexOffsetPairs: " + offsetTypeIndexOffsetPairs); + writer.write("\nlengthTypeIndexOffsetPairs: " + lengthTypeIndexOffsetPairs); + writer.write("\noffsetHashAdjustment: " + offsetHashAdjustment); + writer.write("\nlengthHashAdjustment: " + lengthHashAdjustment); + writer.write("\n"); + PdbReaderUtils.dumpTail(writer, this); } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface800.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface800.java index cfa33df07d..e29640065a 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface800.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/TypeProgramInterface800.java @@ -52,20 +52,13 @@ public class TypeProgramInterface800 extends TypeProgramInterface { @Override protected void dumpHeader(Writer writer) throws IOException { - StringBuilder builder = new StringBuilder(); - builder.append("\nversionNumber: "); - builder.append(versionNumber); - builder.append("\nheaderLength: "); - builder.append(headerLength); - builder.append("\ntypeIndexMin: "); - builder.append(typeIndexMin); - builder.append("\ntypeIndexMaxExclusive: "); - builder.append(typeIndexMaxExclusive); - builder.append("\ndataLength: "); - builder.append(dataLength); - builder.append("\n"); - builder.append(hash.dump()); - writer.write(builder.toString()); + writer.write("\nversionNumber: " + versionNumber); + writer.write("\nheaderLength: " + headerLength); + writer.write("\ntypeIndexMin: " + typeIndexMin); + writer.write("\ntypeIndexMaxExclusive: " + typeIndexMaxExclusive); + writer.write("\ndataLength: " + dataLength); + writer.write("\n"); + hash.dump(writer); } }