mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-28 15:11:44 +00:00
Corrected issue with Program metadata which included CustomerOption.
Cleanup PDB analyzer related error reporting.
This commit is contained in:
parent
4295690e0b
commit
3cd26120a3
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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())) {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user