Corrected issue with Program metadata which included CustomerOption.

Cleanup PDB analyzer related error reporting.
This commit is contained in:
ghidra1 2020-10-08 12:44:41 -04:00
parent 4295690e0b
commit 3cd26120a3
13 changed files with 240 additions and 187 deletions

View File

@ -19,6 +19,7 @@ import java.util.*;
import ghidra.framework.options.*;
import ghidra.program.model.listing.Program;
import ghidra.util.StringUtilities;
/**
* <code>StoredAnalyzerTimes</code> provides a custom option container for
@ -29,6 +30,7 @@ public class StoredAnalyzerTimes implements CustomOption {
public static final String OPTIONS_LIST = Program.PROGRAM_INFO + ".Analysis Times";
public static final String OPTION_NAME = "Times";
// all times maintained in milliseconds
private Map<String, Long> taskTimes = new HashMap<>();
private Long totalTime;
private String[] names;
@ -80,7 +82,7 @@ public class StoredAnalyzerTimes implements CustomOption {
/**
* Add the specified time corresponding to the specified analysis taskName
* @param taskName analysis task name
* @param t time increment
* @param t time increment in milliseconds
*/
public void addTime(String taskName, long t) {
long cumulativeTime = taskTimes.getOrDefault(taskName, 0L) + t;
@ -92,7 +94,7 @@ public class StoredAnalyzerTimes implements CustomOption {
/**
* Get the accumulated time for the specified analysis taskName
* @param taskName analysis task name
* @return accumulated task time or null if entry not found
* @return accumulated task time in milliseconds or null if entry not found
*/
public Long getTime(String taskName) {
return taskTimes.get(taskName);
@ -100,7 +102,8 @@ public class StoredAnalyzerTimes implements CustomOption {
/**
* Get the total accumulated task time for all task entries
* @return total accumuated task time
* in milliseconds
* @return total accumuated task time in milliseconds
*/
public long getTotalTime() {
if (totalTime == null) {
@ -113,6 +116,11 @@ public class StoredAnalyzerTimes implements CustomOption {
return totalTime;
}
@Override
public String toString() {
return formatTimeMS(getTotalTime()) + " seconds";
}
/**
* Get all task names for which time entries exist
* @return array of task names
@ -167,4 +175,11 @@ public class StoredAnalyzerTimes implements CustomOption {
options.putObject(StoredAnalyzerTimes.OPTION_NAME, times);
}
static String formatTimeMS(long timeMS) {
String str = Long.toUnsignedString(timeMS / 1000L);
str += ".";
str += StringUtilities.pad(Long.toUnsignedString(timeMS % 1000L), '0', 3);
return str;
}
}

View File

@ -22,7 +22,6 @@ import javax.swing.*;
import docking.widgets.label.GDLabel;
import ghidra.framework.options.CustomOptionsEditor;
import ghidra.util.StringUtilities;
import ghidra.util.layout.PairLayout;
/**
@ -102,7 +101,7 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
continue;
}
JTextField valueField = new JTextField(formatTimeMS(timeMS));
JTextField valueField = new JTextField(StoredAnalyzerTimes.formatTimeMS(timeMS));
valueField.setEditable(false);
valueField.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(valueField);
@ -112,7 +111,8 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
label.setFont(label.getFont().deriveFont(Font.BOLD));
panel.add(label);
JTextField valueField = new JTextField(formatTimeMS(times.getTotalTime()));
JTextField valueField =
new JTextField(StoredAnalyzerTimes.formatTimeMS(times.getTotalTime()));
valueField.setEditable(false);
valueField.setHorizontalAlignment(SwingConstants.RIGHT);
valueField.setBorder(BorderFactory.createLineBorder(Color.black, 2));
@ -121,11 +121,6 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
return panel;
}
private String formatTimeMS(long timeMS) {
String str = Long.toUnsignedString(timeMS / 1000L);
str += ".";
str += StringUtilities.pad(Long.toUnsignedString(timeMS % 1000L), '0', 3);
return str;
}
}

View File

@ -121,7 +121,7 @@ abstract class AbstractPeDebugLoader extends AbstractLibrarySupportLoader {
proplist.setString(PdbParserConstants.PDB_VERSION, Conv.toString(magic));
proplist.setString(PdbParserConstants.PDB_SIGNATURE, Conv.toHexString(sig));
proplist.setString(PdbParserConstants.PDB_AGE, Conv.toHexString(age));
proplist.setString(PdbParserConstants.PDB_AGE, Integer.toHexString(age));
proplist.setString(PdbParserConstants.PDB_FILE, name);
/*
DebugDirectory dd = dcv.getDebugDirectory();
@ -147,7 +147,7 @@ abstract class AbstractPeDebugLoader extends AbstractLibrarySupportLoader {
proplist.setString(PdbParserConstants.PDB_VERSION, Conv.toString(magic));
proplist.setString(PdbParserConstants.PDB_GUID, guid.toString());
proplist.setString(PdbParserConstants.PDB_AGE, Conv.toHexString(age));
proplist.setString(PdbParserConstants.PDB_AGE, Integer.toHexString(age));
proplist.setString(PdbParserConstants.PDB_FILE, name);
/*
DebugDirectory dd = dcv.getDebugDirectory();

View File

@ -24,6 +24,7 @@ import ghidra.app.util.bin.format.pdb.*;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.PeLoader;
import ghidra.app.util.pdb.PdbLocator;
import ghidra.framework.options.OptionType;
import ghidra.framework.options.Options;
import ghidra.framework.preferences.Preferences;
import ghidra.program.model.address.AddressSetView;
@ -48,10 +49,8 @@ public class PdbAnalyzer extends AbstractAnalyzer {
private static final String SYMBOLPATH_OPTION_NAME = "Symbol Repository Path";
private static final String SYMBOLPATH_OPTION_DESCRIPTION =
"Directory path to root of Microsoft Symbol Repository Directory";
private static final String SYMBOLPATH_OPTION_DEFAULT_VALUE =
PdbLocator.DEFAULT_SYMBOLS_DIR.getAbsolutePath();
private String symbolsRepositoryPath = SYMBOLPATH_OPTION_DEFAULT_VALUE;
private File symbolsRepositoryDir = PdbLocator.DEFAULT_SYMBOLS_DIR;
//==============================================================================================
// Include the PE-Header-Specified PDB path for searching for appropriate PDB file.
@ -62,6 +61,9 @@ public class PdbAnalyzer extends AbstractAnalyzer {
private boolean includePeSpecifiedPdbPath = false;
// only try once per transaction due to extensive error logging which may get duplicated
private long lastTransactionId = -1;
//==============================================================================================
public PdbAnalyzer() {
super(NAME, DESCRIPTION, AnalyzerType.BYTE_ANALYZER);
@ -73,7 +75,24 @@ public class PdbAnalyzer extends AbstractAnalyzer {
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log) {
// Only run once per transaction - avoid message duplication
long txId = program.getCurrentTransaction().getID();
if (txId == lastTransactionId) {
return false;
}
lastTransactionId = txId;
// Only run if restricted set corresponds to entire program
if (!set.contains(program.getMemory())) {
return false;
}
if (PdbParser.isAlreadyLoaded(program)) {
if (!PdbUniversalAnalyzer.isEnabled(program)) { // yield to other analyzer complaining
Msg.info(this, "Skipping PDB analysis since it has previouslu run.");
Msg.info(this, ">> Clear 'PDB Loaded' program property or use Load PDB action if " +
"additional PDB processing required.");
}
return true;
}
@ -105,7 +124,7 @@ public class PdbAnalyzer extends AbstractAnalyzer {
try {
pdb = PdbParser.findPDB(program, includePeSpecifiedPdbPath, symbolsRepositoryPath);
pdb = PdbParser.findPDB(program, includePeSpecifiedPdbPath, symbolsRepositoryDir);
if (pdb == null) {
@ -191,18 +210,15 @@ public class PdbAnalyzer extends AbstractAnalyzer {
String pdbStorageLocation =
Preferences.getProperty(PdbParser.PDB_STORAGE_PROPERTY, null, true);
if (pdbStorageLocation != null) {
File pdbDirectory = new File(pdbStorageLocation);
if (pdbDirectory.isDirectory()) {
options.registerOption(SYMBOLPATH_OPTION_NAME, pdbStorageLocation, null,
SYMBOLPATH_OPTION_DESCRIPTION);
symbolsRepositoryDir = pdbDirectory;
}
}
else {
options.registerOption(SYMBOLPATH_OPTION_NAME, SYMBOLPATH_OPTION_DEFAULT_VALUE, null,
SYMBOLPATH_OPTION_DESCRIPTION);
}
options.registerOption(SYMBOLPATH_OPTION_NAME, OptionType.FILE_TYPE, symbolsRepositoryDir,
null, SYMBOLPATH_OPTION_DESCRIPTION);
options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null,
OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH);
@ -210,19 +226,16 @@ public class PdbAnalyzer extends AbstractAnalyzer {
@Override
public void optionsChanged(Options options, Program program) {
String symbolPath =
options.getString(SYMBOLPATH_OPTION_NAME, SYMBOLPATH_OPTION_DEFAULT_VALUE);
setSymbolsRepositoryPath(symbolPath);
symbolsRepositoryDir =
options.getFile(SYMBOLPATH_OPTION_NAME, PdbLocator.DEFAULT_SYMBOLS_DIR);
Preferences.setProperty(PdbParser.PDB_STORAGE_PROPERTY, symbolPath);
Preferences.setProperty(PdbParser.PDB_STORAGE_PROPERTY,
symbolsRepositoryDir != null ? symbolsRepositoryDir.getAbsolutePath() : null);
Preferences.store();
includePeSpecifiedPdbPath =
options.getBoolean(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath);
}
public void setSymbolsRepositoryPath(String symbolPath) {
symbolsRepositoryPath = symbolPath;
}
}

View File

@ -199,6 +199,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
private PdbReaderOptions pdbReaderOptions;
private PdbApplicatorOptions pdbApplicatorOptions;
// only try once per transaction due to extensive error logging which may get duplicated
private long lastTransactionId = -1;
//==============================================================================================
//==============================================================================================
public PdbUniversalAnalyzer() {
@ -221,6 +224,18 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
// Only run once per transaction - avoid message duplication
long txId = program.getCurrentTransaction().getID();
if (txId == lastTransactionId) {
return false;
}
lastTransactionId = txId;
// Only run if restricted set corresponds to entire program
if (!set.contains(program.getMemory())) {
return false;
}
// NOTE: Legacy PDB Analyzer currently yields to this analyzer if both are enabled
// if (PdbAnalyzer.isEnabled(program)) {
// log.appendMsg(getName(),
@ -246,9 +261,10 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
Msg.info(this,
">> Clear 'PDB Loaded' program property or use Load PDB action if " +
"additional PDB processing required.");
return true;
}
if (programAttributes.isPdbLoaded() ||
failMissingFilename(programAttributes, log) ||
if (failMissingFilename(programAttributes, log) ||
failMissingAttributes(programAttributes, log)) {
return true;
}

View File

@ -29,6 +29,7 @@ import ghidra.app.util.NamespaceUtils;
import ghidra.app.util.SymbolPath;
import ghidra.app.util.importer.LibrarySearchPathManager;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.pdb.PdbLocator;
import ghidra.app.util.pdb.PdbProgramAttributes;
import ghidra.framework.*;
import ghidra.framework.options.Options;
@ -53,7 +54,6 @@ public class PdbParser {
private static final String README_FILENAME =
Application.getInstallationDirectory() + "\\docs\\README_PDB.html";
public final static File SPECIAL_PDB_LOCATION = new File("C:/WINDOWS/Symbols");
public final static String PDB_STORAGE_PROPERTY = "PDB Storage Directory";
static final String STRUCTURE_KIND = "Structure";
@ -1070,12 +1070,12 @@ public class PdbParser {
*
* @param program program for which to find a matching PDB
* @param includePeSpecifiedPdbPath to also check the PE-header-specified PDB path
* @param symbolsRepositoryPath location where downloaded symbols are stored
* @param symbolsRepositoryDir location where downloaded symbols are stored
* @return matching PDB for program, or null
*/
public static File findPDB(Program program, boolean includePeSpecifiedPdbPath,
String symbolsRepositoryPath) {
return findPDB(getPdbAttributes(program), includePeSpecifiedPdbPath, symbolsRepositoryPath,
File symbolsRepositoryDir) {
return findPDB(getPdbAttributes(program), includePeSpecifiedPdbPath, symbolsRepositoryDir,
null);
}
@ -1085,12 +1085,12 @@ public class PdbParser {
*
* @param pdbAttributes PDB attributes associated with the program
* @param includePeSpecifiedPdbPath to also check the PE-header-specified PDB path
* @param symbolsRepositoryPath location of the local symbols repository (can be null)
* @param symbolsRepositoryDir location of the local symbols repository (can be null)
* @param fileType type of file to search for (can be null)
* @return matching PDB file (or null, if not found)
*/
public static File findPDB(PdbProgramAttributes pdbAttributes,
boolean includePeSpecifiedPdbPath, String symbolsRepositoryPath, PdbFileType fileType) {
boolean includePeSpecifiedPdbPath, File symbolsRepositoryDir, PdbFileType fileType) {
// Store potential names of PDB files and potential locations of those files,
// so that all possible combinations can be searched.
@ -1107,7 +1107,7 @@ public class PdbParser {
guidSubdirPaths.add(File.separator + potentialName + File.separator + guidAgeString);
}
return checkPathsForPdb(symbolsRepositoryPath, guidSubdirPaths, potentialPdbNames, fileType,
return checkPathsForPdb(symbolsRepositoryDir, guidSubdirPaths, potentialPdbNames, fileType,
pdbAttributes, includePeSpecifiedPdbPath);
}
@ -1128,7 +1128,7 @@ public class PdbParser {
* symbolsRepositoryPath, then look for .pdb.xml file, then .pdb.xml file in other
* directories.
*
* @param symbolsRepositoryPath location of the local symbols repository (can be null)
* @param symbolsRepositoryDir location of the local symbols repository (can be null)
* @param guidSubdirPaths subdirectory paths (that include the PDB's GUID) that may contain
* a matching PDB
* @param potentialPdbNames all potential filenames for the PDB file(s) that match the program
@ -1136,13 +1136,13 @@ public class PdbParser {
* @param pdbAttributes PDB attributes associated with the program
* @return matching PDB file, if found (else null)
*/
private static File checkPathsForPdb(String symbolsRepositoryPath, Set<String> guidSubdirPaths,
private static File checkPathsForPdb(File symbolsRepositoryDir, Set<String> guidSubdirPaths,
List<String> potentialPdbNames, PdbFileType fileType,
PdbProgramAttributes pdbAttributes, boolean includePeSpecifiedPdbPath) {
File foundPdb = null;
Set<File> symbolsRepoPaths =
getSymbolsRepositoryPaths(symbolsRepositoryPath, guidSubdirPaths);
getSymbolsRepositoryPaths(symbolsRepositoryDir, guidSubdirPaths);
Set<File> predefinedPaths =
getPredefinedPaths(guidSubdirPaths, pdbAttributes, includePeSpecifiedPdbPath);
boolean fileTypeSpecified = (fileType != null);
@ -1169,7 +1169,7 @@ public class PdbParser {
checkForXml = onWindows ? false : true;
// Start by searching in symbolsRepositoryPath, if available.
if (symbolsRepositoryPath != null) {
if (!symbolsRepoPaths.isEmpty()) {
foundPdb = checkSpecificPathsForPdb(symbolsRepoPaths, potentialPdbNames, checkForXml);
}
@ -1195,26 +1195,23 @@ public class PdbParser {
return foundPdb;
}
private static Set<File> getSymbolsRepositoryPaths(String symbolsRepositoryPath,
private static Set<File> getSymbolsRepositoryPaths(File symbolsRepositoryDir,
Set<String> guidSubdirPaths) {
Set<File> symbolsRepoPaths = new LinkedHashSet<>();
// Collect sub-directories of the symbol repository that exist
File symRepoFile;
if (symbolsRepositoryPath != null &&
(symRepoFile = new File(symbolsRepositoryPath)).isDirectory()) {
if (symbolsRepositoryDir != null && symbolsRepositoryDir.isDirectory()) {
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(symRepoFile, guidSubdir);
File testDir = new File(symbolsRepositoryDir, guidSubdir);
if (testDir.isDirectory()) {
symbolsRepoPaths.add(testDir);
}
}
// Check outer folder last
symbolsRepoPaths.add(symRepoFile);
symbolsRepoPaths.add(symbolsRepositoryDir);
}
return symbolsRepoPaths;
@ -1227,7 +1224,8 @@ public class PdbParser {
Set<File> predefinedPaths = new LinkedHashSet<>();
getPathsFromAttributes(pdbAttributes, includePeSpecifiedPdbPath, predefinedPaths);
getWindowsPaths(guidSubdirPaths, predefinedPaths);
getSymbolPaths(PdbLocator.DEFAULT_SYMBOLS_DIR, guidSubdirPaths, predefinedPaths);
getSymbolPaths(PdbLocator.WINDOWS_SYMBOLS_DIR, guidSubdirPaths, predefinedPaths);
getLibraryPaths(guidSubdirPaths, predefinedPaths);
return predefinedPaths;
@ -1253,19 +1251,21 @@ public class PdbParser {
}
}
private static void getWindowsPaths(Set<String> guidSubdirPaths, Set<File> predefinedPaths) {
private static void getSymbolPaths(File symbolsDir, Set<String> guidSubdirPaths,
Set<File> predefinedPaths) {
// Don't have to call .exists(), since .isDirectory() does that already
if (onWindows && SPECIAL_PDB_LOCATION.isDirectory()) {
predefinedPaths.add(SPECIAL_PDB_LOCATION);
if (symbolsDir == null || !symbolsDir.isDirectory()) {
return;
}
predefinedPaths.add(symbolsDir);
// Check alternate locations
String specialPdbPath = SPECIAL_PDB_LOCATION.getAbsolutePath();
// Check alternate locations
String specialPdbPath = symbolsDir.getAbsolutePath();
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(specialPdbPath + guidSubdir);
if (testDir.isDirectory()) {
predefinedPaths.add(testDir);
}
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(specialPdbPath + guidSubdir);
if (testDir.isDirectory()) {
predefinedPaths.add(testDir);
}
}
}

View File

@ -76,15 +76,17 @@ public class PdbLocator {
private static final File USER_HOME = new File(System.getProperty("user.home"));
public static final File DEFAULT_SYMBOLS_DIR =
onWindows ? new File("C:\\Symbols") : new File(USER_HOME, "Symbols");
public final static File WINDOWS_SYMBOLS_DIR =
onWindows ? new File("C:/WINDOWS/Symbols") : null;
private File symbolsRepositoryPath;
private File symbolsRepositoryDir;
/**
* Only holds identifies in PDBs up until a matching one was found--nothing beyond that.
*/
private Map<String, PdbIdentifiers> identifiersByFilePath = new HashMap<>();
public PdbLocator(File symbolsRepositoryPath) {
this.symbolsRepositoryPath = symbolsRepositoryPath;
public PdbLocator(File symbolsRepositoryDir) {
this.symbolsRepositoryDir = symbolsRepositoryDir;
}
//==============================================================================================
@ -219,7 +221,7 @@ public class PdbLocator {
try {
List<String> orderedListOfExistingFileNames = findPDB(new PdbProgramAttributes(program),
includePeSpecifiedPdbPath, symbolsRepositoryPath.getAbsolutePath());
includePeSpecifiedPdbPath, symbolsRepositoryDir);
if (orderedListOfExistingFileNames.isEmpty()) {
String pdbName = program.getOptions(Program.PROGRAM_INFO)
@ -371,7 +373,7 @@ public class PdbLocator {
Integer signature = (attributes.getPdbSignature() == null) ? null
: Integer.valueOf(attributes.getPdbSignature());
return formatPdbIdentifiers(attributes.getPdbFile(), signature,
Integer.valueOf(attributes.getPdbAge()), attributes.getPdbGuid());
Integer.valueOf(attributes.getPdbAge(), 16), attributes.getPdbGuid());
}
private StringBuilder formatPdbIdentifiers(String file, PdbIdentifiers identifiers) {
@ -386,8 +388,8 @@ public class PdbLocator {
if (signature != null) {
builder.append(String.format("; Signature: 0X%08X", signature));
}
builder.append("; Age: ");
builder.append(age);
builder.append("; Age: 0x");
builder.append(Integer.toHexString(age));
if (guidString != null) {
builder.append("; GUID: ");
builder.append(guidString);
@ -404,12 +406,12 @@ public class PdbLocator {
* @param pdbAttributes PDB attributes associated with the program.
* @param includePeSpecifiedPdbPath {@code true} if looking for PDB in PE-Header-Specified
* path location, which may be unsafe security-wise.
* @param symbolsRepositoryPathIn Location of the local symbols repository (can be null).
* @param symbolsRepositoryDir Location of the local symbols repository (can be null).
* @return matching PDB file (or null, if not found).
* @throws PdbException if there was a problem with the PDB attributes.
*/
private List<String> findPDB(PdbProgramAttributes pdbAttributes,
boolean includePeSpecifiedPdbPath, String symbolsRepositoryPathIn) throws PdbException {
private static List<String> findPDB(PdbProgramAttributes pdbAttributes,
boolean includePeSpecifiedPdbPath, File symbolsRepositoryDir) throws PdbException {
// Store potential names of PDB files and potential locations of those files,
// so that all possible combinations can be searched.
@ -428,7 +430,7 @@ public class PdbLocator {
guidSubdirPaths.add(File.separator + potentialName + File.separator + guidAgeString);
}
return checkPathsForPdb(symbolsRepositoryPathIn, guidSubdirPaths, potentialPdbNames,
return checkPathsForPdb(symbolsRepositoryDir, guidSubdirPaths, potentialPdbNames,
pdbAttributes, includePeSpecifiedPdbPath);
}
@ -450,7 +452,7 @@ public class PdbLocator {
* symbolsRepositoryPath, then look for .pdb.xml file, then .pdb.xml file in other
* directories.
*
* @param symbolsRepositoryPath location of the local symbols repository (can be null)
* @param symbolsRepositoryDir location of the local symbols repository (can be null)
* @param guidSubdirPaths subdirectory paths (that include the PDB's GUID) that may contain
* a matching PDB
* @param potentialPdbNames all potential filenames for the PDB file(s) that match the program
@ -460,19 +462,19 @@ public class PdbLocator {
* enabled unless binary source is trusted and PDB file path is reasonable for this system.
* @return matching PDB file, if found (else null)
*/
private static List<String> checkPathsForPdb(String symbolsRepositoryPath,
private static List<String> checkPathsForPdb(File symbolsRepositoryDir,
Set<String> guidSubdirPaths, List<String> potentialPdbNames,
PdbProgramAttributes pdbAttributes, boolean includePeSpecifiedPdbPath) {
Set<File> symbolsRepoPaths =
getSymbolsRepositoryPaths(symbolsRepositoryPath, guidSubdirPaths);
getSymbolsRepositoryPaths(symbolsRepositoryDir, guidSubdirPaths);
Set<File> predefinedPaths =
getPredefinedPaths(guidSubdirPaths, pdbAttributes, includePeSpecifiedPdbPath);
// Start by searching in symbolsRepositoryPath, if available.
// Start by searching in symbolsRepositoryDir, if available.
List<String> orderedListOfExistingFileNames = new ArrayList<>();
if (symbolsRepositoryPath != null) {
if (!symbolsRepoPaths.isEmpty()) {
orderedListOfExistingFileNames
.addAll(checkSpecificPathsForPdb(symbolsRepoPaths, potentialPdbNames));
}
@ -494,26 +496,23 @@ public class PdbLocator {
}
//==============================================================================================
private static Set<File> getSymbolsRepositoryPaths(String symbolsRepositoryPath,
private static Set<File> getSymbolsRepositoryPaths(File symbolsRepositoryDir,
Set<String> guidSubdirPaths) {
Set<File> symbolsRepoPaths = new LinkedHashSet<>();
// Collect sub-directories of the symbol repository that exist
File symRepoFile;
if (symbolsRepositoryPath != null &&
(symRepoFile = new File(symbolsRepositoryPath)).isDirectory()) {
if (symbolsRepositoryDir != null && symbolsRepositoryDir.isDirectory()) {
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(symRepoFile, guidSubdir);
File testDir = new File(symbolsRepositoryDir, guidSubdir);
if (testDir.isDirectory()) {
symbolsRepoPaths.add(testDir);
}
}
// Check outer folder last
symbolsRepoPaths.add(symRepoFile);
symbolsRepoPaths.add(symbolsRepositoryDir);
}
return symbolsRepoPaths;
@ -527,7 +526,8 @@ public class PdbLocator {
Set<File> predefinedPaths = new LinkedHashSet<>();
getPathsFromAttributes(pdbAttributes, includePeSpecifiedPdbPath, predefinedPaths);
getWindowsPaths(guidSubdirPaths, predefinedPaths);
getSymbolPaths(DEFAULT_SYMBOLS_DIR, guidSubdirPaths, predefinedPaths);
getSymbolPaths(WINDOWS_SYMBOLS_DIR, guidSubdirPaths, predefinedPaths);
getLibraryPaths(guidSubdirPaths, predefinedPaths);
return predefinedPaths;
@ -566,20 +566,22 @@ public class PdbLocator {
* <li>C:\MySymbols\symbols\ext
* <P>
*/
private static void getWindowsPaths(Set<String> guidSubdirPaths, Set<File> predefinedPaths) {
private static void getSymbolPaths(File symbolsDir, Set<String> guidSubdirPaths,
Set<File> predefinedPaths) {
// TODO: Need to provide better control of symbol directory preference
// instead of only using default
if (DEFAULT_SYMBOLS_DIR.isDirectory()) {
predefinedPaths.add(DEFAULT_SYMBOLS_DIR);
if (symbolsDir == null || !symbolsDir.isDirectory()) {
return;
}
predefinedPaths.add(symbolsDir);
// Check alternate locations
String specialPdbPath = DEFAULT_SYMBOLS_DIR.getAbsolutePath();
// Check alternate locations
String specialPdbPath = symbolsDir.getAbsolutePath();
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(specialPdbPath + guidSubdir);
if (testDir.isDirectory()) {
predefinedPaths.add(testDir);
}
for (String guidSubdir : guidSubdirPaths) {
File testDir = new File(specialPdbPath + guidSubdir);
if (testDir.isDirectory()) {
predefinedPaths.add(testDir);
}
}
}

View File

@ -28,7 +28,7 @@ import ghidra.program.model.listing.Program;
*/
public class PdbProgramAttributes {
private String pdbAge;
private String pdbAge; // hex format
private String pdbGuid;
private String pdbSignature;
@ -78,6 +78,10 @@ public class PdbProgramAttributes {
createGuidAgeString();
}
/**
* PDB Age as a hex value
* @return PDB Age as a hex value
*/
public String getPdbAge() {
return pdbAge;
}

View File

@ -217,8 +217,7 @@ public class PdbSymbolServerPlugin extends Plugin {
localDir = askForLocalStorageLocation();
// 3. See if PDB can be found locally
File pdbFile = PdbParser.findPDB(pdbAttributes, includePePdbPath,
localDir.getAbsolutePath(), fileType);
File pdbFile = PdbParser.findPDB(pdbAttributes, includePePdbPath, localDir, fileType);
// 4. If not found locally, ask if it should be retrieved
if (pdbFile != null && pdbFile.getName().endsWith(fileType.toString())) {

View File

@ -44,7 +44,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
private static String notepadGUID = "36cfd5f9-888c-4483-b522-b9db242d8478";
// Note: this is in hex. Code should translate it to decimal when creating GUID/Age folder name
private static String notepadAge = "00000021";
private static String notepadAge = "21";
// Name of subfolder that stores the actual PDB file
private static String guidAgeCombo = "36CFD5F9888C4483B522B9DB242D847833";
@ -54,8 +54,8 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
private Program testProgram;
//private static String guidAgeCombo = PdbParserNEW.getGuidAgeString(notepadGUID, notepadAge);
// Default repo path that is hard-coded into the PDB analyzer settings
private static String defaultSymbolsRepoPath = "C:/Symbols";
// Bogus symbol repository directory or null directory should not break anything
private static final File noSuchSymbolsRepoDir = null;
private String pdbFilename, pdbXmlFilename;
private String exeFolderName = "exe", pdbXmlFolderName = "pdb_xml",
@ -269,28 +269,24 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
assertNotNull(pdbFile);
expectedDir1 = new File(fileLocation, pdbFilename);
expectedDir2 = new File(expectedDir1, guidAgeCombo);
assertEquals(expectedDir2.getAbsolutePath(),
pdbFile.getParentFile().getAbsolutePath());
assertEquals(expectedDir2, pdbFile.getParentFile());
break;
case SAME_AS_EXE_NO_SUBDIR:
assertNotNull(pdbFile);
assertEquals(fileLocation.getAbsolutePath(),
pdbFile.getParentFile().getAbsolutePath());
assertEquals(fileLocation, pdbFile.getParentFile());
break;
case SYMBOLS_SUBDIR:
assertNotNull(pdbFile);
expectedDir1 = new File(symbolsFolder, pdbFilename);
expectedDir2 = new File(expectedDir1, guidAgeCombo);
assertEquals(expectedDir2.getAbsolutePath(),
pdbFile.getParentFile().getAbsolutePath());
assertEquals(expectedDir2, pdbFile.getParentFile());
break;
case SYMBOLS_NO_SUBDIR:
assertNotNull(pdbFile);
assertEquals(symbolsFolder.getAbsolutePath(),
pdbFile.getParentFile().getAbsolutePath());
assertEquals(symbolsFolder, pdbFile.getParentFile());
break;
default:
@ -300,14 +296,12 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
switch (pdbXmlLoc) {
case SAME_AS_PDB:
assertNotNull(pdbXmlFile);
assertEquals(pdbXmlFile.getParentFile().getAbsolutePath(),
pdbFile.getParentFile().getAbsolutePath());
assertEquals(pdbXmlFile.getParentFile(), pdbFile.getParentFile());
break;
case OWN_DIR:
assertNotNull(pdbXmlFile);
assertEquals(pdbXmlFile.getParentFile().getAbsolutePath(),
pdbXmlDir.getAbsolutePath());
assertEquals(pdbXmlFile.getParentFile(), pdbXmlDir);
break;
case NONE:
@ -338,7 +332,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = null;
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
// Should not find anything since repo is set to an invalid path
assertNull(pdb);
@ -360,10 +354,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -382,15 +376,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -409,10 +403,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
assertEquals(pdb.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdb, pdb);
}
@ -431,15 +425,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -458,10 +452,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -479,7 +473,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
// Should not find anything since repo is set to an invalid path
assertNull(pdb);
@ -500,15 +494,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -527,10 +521,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, symbolsFolder);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -549,15 +543,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SYMBOLS_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -576,10 +570,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -597,7 +591,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
// Should not find anything since repo is set to an invalid path
assertNull(pdb);
@ -618,15 +612,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -645,10 +639,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -667,15 +661,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlFile.getParentFile());
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -697,10 +691,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -719,10 +713,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -744,10 +738,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
@ -769,15 +763,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -796,15 +790,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.SAME_AS_PDB);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParent());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -823,10 +817,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
/**
@ -844,10 +838,10 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile().getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbFile.getParentFile());
assertNotNull(pdb);
assertEquals(pdbFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbFile, pdb);
}
/**
@ -868,15 +862,15 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.SAME_AS_EXE_NO_SUBDIR, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
@ -895,7 +889,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.NONE);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
assertNull(pdb);
}
@ -915,7 +909,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, defaultSymbolsRepoPath);
File pdb = PdbParser.findPDB(testProgram, false, noSuchSymbolsRepoDir);
assertNull(pdb);
}
@ -935,22 +929,22 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createdFiles = createFiles(PdbLocation.NONE, PdbXmlLocation.OWN_DIR);
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
assertNotNull(pdb);
if (PdbParser.onWindows) {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
else {
assertEquals(pdbXmlFile.getAbsolutePath(), pdb.getAbsolutePath());
assertEquals(pdbXmlFile, pdb);
}
}
private void createDirectory(File directory) {
directory.mkdir();
if (!directory.isDirectory()) {
fail("Should have created directory: " + directory.getAbsolutePath());
fail("Should have created directory: " + directory);
}
}
@ -961,7 +955,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
createSuccess = file.createNewFile();
if (!createSuccess) {
fail("Failed creation of file: " + file.getAbsolutePath());
fail("Failed creation of file: " + file);
}
}
catch (IOException ioe) {
@ -1002,7 +996,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
xmlBuffWriter.close();
}
catch (IOException ioe) {
fail("IOException writing to temporary file (" + pdbXmlFile.getAbsolutePath() + "). " +
fail("IOException writing to temporary file (" + pdbXmlFile + "). " +
ioe.toString());
}
@ -1015,7 +1009,7 @@ public class PdbParserTest extends AbstractGhidraHeadlessIntegrationTest {
buildPdbXml();
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir.getAbsolutePath());
File pdb = PdbParser.findPDB(testProgram, false, pdbXmlDir);
AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager(testProgram);
DataTypeManagerService dataTypeManagerService = mgr.getDataTypeManagerService();

View File

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,4 +31,14 @@ public interface CustomOption {
*/
public void writeState(SaveState saveState);
/**
* CustomOption should implement this method to provide a formatted
* string value of this option value. The returned value will
* be used in support of the {@link Options#getValueAsString(String)}
* and {@link Options#getDefaultValueAsString(String)}.
* @return option value as string
*/
@Override
public String toString();
}

View File

@ -540,18 +540,18 @@ public class DataTypeArchiveDB extends DomainObjectAdapterDB
Options propList = getOptions(Program.PROGRAM_INFO);
List<String> propNames = propList.getOptionNames();
Collections.sort(propNames);
for (String name : propNames) {
metadata.put(name, propList.getValueAsString(name));
for (String propName : propNames) {
if (propName.indexOf(Options.DELIMITER) >= 0) {
continue; // ignore second tier options
}
String valueAsString = propList.getValueAsString(propName);
if (valueAsString != null) {
metadata.put(propName, propList.getValueAsString(propName));
}
}
return metadata;
}
// private static String getString(Object obj) {
// if (obj != null) {
// return obj.toString();
// }
// return null;
// }
@Override
protected void updateMetadata() throws IOException {
getMetadata(); // updates metadata map

View File

@ -2360,7 +2360,13 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
List<String> propNames = propList.getOptionNames();
Collections.sort(propNames);
for (String propName : propNames) {
metadata.put(propName, propList.getValueAsString(propName));
if (propName.indexOf(Options.DELIMITER) >= 0) {
continue; // ignore second tier options
}
String valueAsString = propList.getValueAsString(propName);
if (valueAsString != null) {
metadata.put(propName, propList.getValueAsString(propName));
}
}
return metadata;
}