From a19571e718033a0744027dbb88e291d1aa5959eb Mon Sep 17 00:00:00 2001 From: ghizard <50744617+ghizard@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:40:28 +0000 Subject: [PATCH] GP-4968 - PDB U source lines --- .../pdbapplicator/PdbApplicatorOptions.java | 25 ++----- .../PdbSourceLinesApplicator.java | 74 ++++++++++++++----- 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicatorOptions.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicatorOptions.java index 83c3415257..8ab3eb58b4 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicatorOptions.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicatorOptions.java @@ -43,11 +43,11 @@ public class PdbApplicatorOptions { // Apply Source Line Numbers. private static final String OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS = - "Apply Source Line Numbers"; // DWARF says "Output Source Line Info", but we use "Apply" + "Import Source Line Info"; private static final String OPTION_DESCRIPTION_APPLY_SOURCE_LINE_NUMBERS = "Create source map entries containing the source code filename, line number, address, and" + " length at each location provided in the PDB data."; - private static final boolean DEFAULT_APPLY_SOURCE_LINE_NUMBERS = false; + private static final boolean DEFAULT_APPLY_SOURCE_LINE_NUMBERS = true; private boolean applySourceLineNumbers; // Apply Code Block Comments. @@ -190,10 +190,9 @@ public class PdbApplicatorOptions { private void registerOptions(Options options, boolean enableControl) { HelpLocation help = null; - //TODO: Uncomment the following for GP-3883 -// options.registerOption(OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, -// applySourceLineNumbers, help, -// OPTION_DESCRIPTION_APPLY_SOURCE_LINE_NUMBERS); + options.registerOption(OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, + applySourceLineNumbers, help, + OPTION_DESCRIPTION_APPLY_SOURCE_LINE_NUMBERS); if (DEVELOPER_MODE || enableControl) { options.registerOption(OPTION_NAME_PROCESSING_CONTROL, PdbApplicatorControl.ALL, help, @@ -203,11 +202,6 @@ public class PdbApplicatorOptions { // PdbApplicatorOptions if (DEVELOPER_MODE) { - //TODO: Remove the following line for GP-3883 - options.registerOption(OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, - applySourceLineNumbers, help, - OPTION_DESCRIPTION_APPLY_SOURCE_LINE_NUMBERS); - options.registerOption(OPTION_NAME_APPLY_CODE_SCOPE_BLOCK_COMMENTS, applyCodeScopeBlockComments, help, OPTION_DESCRIPTION_APPLY_CODE_SCOPE_BLOCK_COMMENTS); @@ -251,9 +245,8 @@ public class PdbApplicatorOptions { private void loadOptions(Options options, boolean enableControl) { - //TODO: Uncomment the following for GP-3883 -// applySourceLineNumbers = options.getBoolean( -// OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, applySourceLineNumbers); + applySourceLineNumbers = options.getBoolean( + OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, applySourceLineNumbers); if (DEVELOPER_MODE || enableControl) { control = options.getEnum(OPTION_NAME_PROCESSING_CONTROL, PdbApplicatorControl.ALL); @@ -262,10 +255,6 @@ public class PdbApplicatorOptions { // PdbApplicatorOptions if (DEVELOPER_MODE) { - //TODO: Remove the following line for GP-3883 - applySourceLineNumbers = options.getBoolean( - OPTION_NAME_APPLY_SOURCE_LINE_NUMBERS, applySourceLineNumbers); - applyCodeScopeBlockComments = options.getBoolean( OPTION_NAME_APPLY_CODE_SCOPE_BLOCK_COMMENTS, applyCodeScopeBlockComments); diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbSourceLinesApplicator.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbSourceLinesApplicator.java index 11f4871e5b..22745023b0 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbSourceLinesApplicator.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbSourceLinesApplicator.java @@ -21,9 +21,16 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*; import ghidra.app.util.bin.format.pdb2.pdbreader.Module; import ghidra.app.util.bin.format.pdb2.pdbreader.type.*; import ghidra.app.util.importer.MessageLog; +import ghidra.framework.store.LockException; +import ghidra.program.database.sourcemap.SourceFile; +import ghidra.program.database.sourcemap.SourceFileIdType; import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.listing.*; +import ghidra.program.model.sourcemap.SourceFileManager; import ghidra.util.Msg; +import ghidra.util.SourceFileUtils; +import ghidra.util.exception.AssertException; import ghidra.util.exception.CancelledException; /** @@ -38,7 +45,7 @@ public class PdbSourceLinesApplicator { private Map
functionLengthByAddress; -// private SourceFileManager manager; + private SourceFileManager manager; //============================================================================================== /** @@ -56,7 +63,7 @@ public class PdbSourceLinesApplicator { functionLengthByAddress = new HashMap<>(); - //manager = program.getSourceFileManager(); + manager = program.getSourceFileManager(); } //============================================================================================== @@ -338,13 +345,39 @@ public class PdbSourceLinesApplicator { } //============================================================================================== - // Temporary mock class - private static class SourceFile { - // Empty - } - + // Processing in the section is geared toward C13 records processing. Have not evaluated its + // usefulness for C11 records + /** + * Finds or creates a SourceFile for our checksum and file ID for C13 processing + * @param fileChecksums the set of FileChecksumC13Sections for this module + * @param fileId the file ID found in the source line records + * @return the source file + */ private SourceFile getSourceFile(FileChecksumsC13Section fileChecksums, int fileId) { - return new SourceFile(); + + // Note: fileId is an offset into the checksum table, so we have them stored in a map. + C13FileChecksum checksumInfo = fileChecksums.getFileChecksumByOffset(fileId); + + Long offsetFilename = checksumInfo.getOffsetFilename(); + String filename = pdb.getNameStringFromOffset(offsetFilename.intValue()); + SourceFileIdType idType = switch (checksumInfo.getChecksumTypeValue()) { + case 0 -> SourceFileIdType.NONE; + case 1 -> SourceFileIdType.MD5; + case 2 -> SourceFileIdType.SHA1; + case 3 -> SourceFileIdType.SHA256; + default -> SourceFileIdType.UNKNOWN; + }; + byte[] identifier = checksumInfo.getChecksumBytes(); + + SourceFile sourceFile = + SourceFileUtils.getSourceFileFromPathString(filename, idType, identifier); + try { + manager.addSourceFile(sourceFile); + } + catch (LockException e) { + throw new AssertionError("LockException after exclusive access verified!"); + } + return sourceFile; } //============================================================================================== @@ -363,16 +396,21 @@ public class PdbSourceLinesApplicator { return; } -// try { -// manager.addSourceMapEntry(sourceFile, start, address, length); -// } -// catch (LockException e) { -// throw new AssertException("LockException after exclusive access verified!"); -// } -// catch (AddressOverflowException e) { -// log.appendMsg("PDB", "AddressOverflow for source map info: %s, %d, %s, %d" -// .formatted(sourceFile.getPath(), start, address.toString(), length)); -// } + try { + manager.addSourceMapEntry(sourceFile, start, address, length); + } + catch (LockException e) { + throw new AssertException("LockException after exclusive access verified!"); + } + catch (AddressOverflowException e) { + log.appendMsg("PDB", "AddressOverflow for source map info: %s, %d, %s, %d" + .formatted(sourceFile.getPath(), start, address.toString(), length)); + } + catch (IllegalArgumentException e) { + // thrown by SourceFileManager.addSourceMapEntry if the new entry conflicts + // with an existing entry or if sourceFile is not associated with manager + log.appendMsg("PDB", e.getMessage()); + } } }