diff --git a/Ghidra/Features/PDB/certification.manifest b/Ghidra/Features/PDB/certification.manifest
index dce9dc413e..8ae04a48be 100644
--- a/Ghidra/Features/PDB/certification.manifest
+++ b/Ghidra/Features/PDB/certification.manifest
@@ -16,13 +16,14 @@ src/main/help/help/shared/redo.png||GHIDRA||||END|
src/main/help/help/shared/tip.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/help/help/shared/undo.png||GHIDRA||||END|
src/main/help/help/shared/warning.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
-src/main/help/help/topics/Pdb/LoadPDBNew.html||GHIDRA||||END|
+src/main/help/help/topics/Pdb/LoadPDB.html||GHIDRA||||END|
src/main/help/help/topics/Pdb/PDB.htm||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/Plus2.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/SymbolServerConfig_AddButtonMenu.png||GHIDRA||||END|
+src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/SymbolServerConfig_Screenshot.png||GHIDRA||||END|
src/main/help/help/topics/Pdb/images/disk.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/help/help/topics/Pdb/images/down.png||GHIDRA||||END|
diff --git a/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml b/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml
index 16c4f1abb5..3ddcfbbd9b 100644
--- a/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml
+++ b/Ghidra/Features/PDB/src/main/help/help/TOC_Source.xml
@@ -51,7 +51,7 @@
Allows the user to configure the location where PDB symbol files are stored and additional locations to search for
- existing PDB files. This is also available in the Load PDB File, Advanced screen.myprogram.pdb/012345670123012301230123456789AB1/myprogram.pdb.myprogram.pdb is the name of the file and the name of the initial subdirectory off the root of the server.012345670123012301230123456789AB is the 32 character hexadecimal value (made up for this example) of the GUID
- "012345678-0123-0123-0123-0123456789AB" of the PDB file.1 is the hexadecimal value of the 'age' (build number) of the PDB file. Note: most PDB files will have an age value of 1.
-
@@ -88,16 +82,10 @@
which PDB file to choose.
-
+ helloworld.pdb and hellokitty.pdb would both be found as possible matches when searching for
- hello.pdb.
-
- /home/your_id/Symbols or C:\Users\your_name\Symbols.
button.
- The Microsoft symbol server and Program's Import Location are good defaults.
button.
Symbol Server Config
button.
button.
(Add)PDB files can be loaded in two ways:
-
- File → Load PDB File
+- File → Load PDB File
- PDB Analyzer via Analysis → Auto Analyze or Analysis → One Shot. @@ -124,7 +124,7 @@ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png index d713737905..5b016a1932 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_NeedsConfig.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png index 14c0387613..bbc03dd825 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Advanced_Screenshot.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png index 3c89aaaf55..79763a7b45 100644 Binary files a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/LoadPdb_Initial_Screenshot.png differ diff --git a/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png new file mode 100644 index 0000000000..ec5d9ea547 Binary files /dev/null and b/Ghidra/Features/PDB/src/main/help/help/topics/Pdb/images/SymbolServerConfig_Configured.png differ diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java index 159aa9c1e4..49c66c8f69 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/LocalSymbolStore.java @@ -204,26 +204,22 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor List
matches = new ArrayList<>(); - // search for exact matches using the built-in logic in AbstractSymbolServer if (storageLevel != 0) { + // search for exact matches using the built-in logic in AbstractSymbolServer matches.addAll(super.find(symbolFileInfo, options, monitor)); - } - if (storageLevel == 0 || options.contains(FindOption.ANY_AGE) || - options.contains(FindOption.ANY_ID)) { - - try { - if (storageLevel == 0) { - searchLevel0(rootDir, this, symbolFileInfo, options, matches, monitor); - } - else { + if (options.contains(FindOption.ANY_AGE) || options.contains(FindOption.ANY_ID)) { + try { searchLevelN(symbolFileInfo, options, matches, monitor); } + catch (IOException ioe) { + Msg.warn(this, + "Error searching for " + symbolFileInfo.getName() + " in " + rootDir, ioe); + } } - catch (IOException ioe) { - Msg.warn(this, "Error searching for " + symbolFileInfo.getName() + " in " + rootDir, - ioe); - } + } + else { + searchLevel0(rootDir, this, symbolFileInfo, options, matches, monitor); } return matches; @@ -232,18 +228,14 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor static void searchLevel0(File rootDir, SymbolStore symbolStore, SymbolFileInfo symbolFileInfo, Set options, List matches, TaskMonitor monitor) { - // if its a "0 level" bag-of-files, we have to open each Pdb to find its UID and - // AGE (after filtering for similar filenames as requested pdb file) - for (File f : list(rootDir, - ff -> ff.isFile() && isFilenameStartsWithMatch(symbolFileInfo, ff))) { - if (monitor.isCancelled()) { - break; - } - SymbolFileInfo fileInfo = SymbolFileInfo.fromFile(f, monitor); - if (fileInfo != null) { - if (hasSymbolFileInfoMatch(symbolFileInfo, fileInfo, options)) { - matches.add(new SymbolFileLocation(f.getName(), symbolStore, fileInfo)); - } + File f = new File(rootDir, symbolFileInfo.getName()); + if (!f.isFile()) { + return; + } + SymbolFileInfo fileInfo = SymbolFileInfo.fromFile(f, monitor); + if (fileInfo != null) { + if (hasSymbolFileInfoMatch(symbolFileInfo, fileInfo, options)) { + matches.add(new SymbolFileLocation(f.getName(), symbolStore, fileInfo)); } } } @@ -402,24 +394,6 @@ public class LocalSymbolStore extends AbstractSymbolServer implements SymbolStor return files != null ? files : new File[] {}; } - static boolean isFilenameStartsWithMatch(SymbolFileInfo symbolFileInfo, File file) { - String symbolFilenameNoExtension = FilenameUtils.getBaseName(symbolFileInfo.getName()); - String fileNoExtension = FilenameUtils.getBaseName(file.getName()); - - // use case-insensitive compare since these are PDB files, which - // come from a Windows env - if (!fileNoExtension.toLowerCase().startsWith(symbolFilenameNoExtension.toLowerCase())) { - return false; - } - - // match on ext ("pdb"), compressed ext ("pd_") - String symbolFilenameExtension = - FilenameUtils.getExtension(symbolFileInfo.getName()).toLowerCase(); - String fileExtension = FilenameUtils.getExtension(file.getName()).toLowerCase(); - return fileExtension.equals(symbolFilenameExtension) || - fileExtension.equals(makeCompressedExtension(symbolFilenameExtension)); - } - static boolean hasSymbolFileInfoMatch(SymbolFileInfo symbolFileInfo, SymbolFileInfo otherSymbolFileInfo, Set options) { boolean idMatches = diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java index 18034e8399..0c1655d752 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/SameDirSymbolStore.java @@ -15,9 +15,8 @@ */ package pdb.symbolserver; -import java.util.*; - import java.io.*; +import java.util.*; import ghidra.util.task.TaskMonitor; @@ -25,8 +24,6 @@ import ghidra.util.task.TaskMonitor; * A Pdb symbol server / symbol store, similar to the {@link LocalSymbolStore}, * but limited to searching just the single directory that the original executable is located in. * - * Matches symbol files that have a similar name to the requested symbol file (but the identifier - * info - guid/id & age must still match as per the find options specified). * */ public class SameDirSymbolStore implements SymbolStore { @@ -105,8 +102,8 @@ public class SameDirSymbolStore implements SymbolStore { @Override public String getDescriptiveName() { - return String.format(PROGRAMS_IMPORT_LOCATION_DESCRIPTION_STR + " - %s", - isValid() ? rootDir.getPath() : "unspecified"); + return PROGRAMS_IMPORT_LOCATION_DESCRIPTION_STR + + (isValid() ? " - " + rootDir.getPath() : ""); } @Override diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java index cbeb0de846..ce2d6f46d4 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/ConfigPdbDialog.java @@ -15,23 +15,25 @@ */ package pdb.symbolserver.ui; +import java.util.List; + import docking.DialogComponentProvider; import docking.DockingWindowManager; -import docking.widgets.OptionDialog; -import pdb.symbolserver.SymbolServerInstanceCreatorRegistry; -import pdb.symbolserver.SymbolServerService; +import pdb.symbolserver.*; /** * Dialog that allows the user to configure the Pdb search locations and symbol directory */ public class ConfigPdbDialog extends DialogComponentProvider { - public static void showSymbolServerConfig() { + public static boolean showSymbolServerConfig() { ConfigPdbDialog choosePdbDialog = new ConfigPdbDialog(); DockingWindowManager.showDialog(choosePdbDialog); + return choosePdbDialog.wasSuccess; } private SymbolServerPanel symbolServerConfigPanel; + private boolean wasSuccess; public ConfigPdbDialog() { super("Configure Symbol Server Search", true, false, true, false); @@ -46,12 +48,10 @@ public class ConfigPdbDialog extends DialogComponentProvider { @Override protected void okCallback() { - if (symbolServerConfigPanel.isConfigChanged() && - OptionDialog.showYesNoDialog(getComponent(), - "Save Configuration", - "Symbol server configuration changed. Save?") == OptionDialog.YES_OPTION) { + if (symbolServerConfigPanel.isConfigChanged()) { symbolServerConfigPanel.saveConfig(); } + wasSuccess = true; close(); } @@ -76,4 +76,23 @@ public class ConfigPdbDialog extends DialogComponentProvider { addCancelButton(); setDefaultButton(cancelButton); } + + /** + * Screen shot usage only + */ + public void pushAddLocationButton() { + symbolServerConfigPanel.pushAddLocationButton(); + } + + /** + * Screen shot only + * + * @param fakeDirectoryText fake text to display in the storage directory text field + * @param symbolServers list of symbol servers to force set + */ + public void setSymbolServerService(String fakeDirectoryText, + List
symbolServers) { + symbolServerConfigPanel.setSymbolServers(symbolServers); + symbolServerConfigPanel.setSymbolStorageDirectoryTextOnly(fakeDirectoryText); + } } diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java index cf234ea194..516effa84e 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java @@ -107,10 +107,10 @@ public class LoadPdbDialog extends DialogComponentProvider { private List > statusTextSuppliers = new ArrayList<>(); private Set lastSearchOptions; private boolean searchCanceled; + private boolean hasShownAdvanced; private Program program; - private SymbolServerPanel symbolServerConfigPanel; private SymbolFilePanel symbolFilePanel; private JTextField programNameTextField; @@ -123,6 +123,7 @@ public class LoadPdbDialog extends DialogComponentProvider { private HintTextField pdbLocationTextField; private GIconLabel exactMatchIconLabel; + private JButton configButton; private JToggleButton advancedToggleButton; private GhidraFileChooser chooser; @@ -153,14 +154,17 @@ public class LoadPdbDialog extends DialogComponentProvider { if (programSymbolFileInfo == null) { programSymbolFileInfo = SymbolFileInfo.unknown("missing"); } - this.symbolServerInstanceCreatorContext = - SymbolServerInstanceCreatorRegistry.getInstance().getContext(program); - this.symbolServerService = - PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); - + updateSymbolServerServiceInstanceFromPreferences(); build(); } + private void updateSymbolServerServiceInstanceFromPreferences() { + symbolServerInstanceCreatorContext = + SymbolServerInstanceCreatorRegistry.getInstance().getContext(program); + symbolServerService = + PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); + } + @Override protected void dialogShown() { pdbPathTextField.setText(programSymbolFileInfo.getPath()); @@ -169,32 +173,7 @@ public class LoadPdbDialog extends DialogComponentProvider { programNameTextField.setText(program.getName()); cancelButton.requestFocusInWindow(); - executeMonitoredRunnable("Search for PDB using built-in locations", true, true, 0, - this::doInitialDefaultSearch); - } - - private void doInitialDefaultSearch(TaskMonitor monitor) { - try { - List results = - symbolServerService.find(programSymbolFileInfo, FindOption.NO_OPTIONS, monitor); - if (!results.isEmpty()) { - SymbolFileLocation symbolFileLocation = - symbolServerService.getLocalSymbolFileLocation(results.get(0), monitor); - File symbolFile = getLocalSymbolFile(symbolFileLocation); - Swing.runLater(() -> { - setSearchResults(results, null); - setPdbLocationValue(symbolFileLocation, symbolFile); - setSelectedPdbFile(symbolFileLocation); - selectRowByLocation(symbolFileLocation); - updateStatusText(); - updateButtonEnablement(); - updateParserOptionEnablement(true); - }); - } - } - catch (CancelledException | IOException e) { - // ignore - } + searchForPdbs(false); } @Override @@ -212,33 +191,9 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolFilePanel.setFindOptions(options); } - /** - * For screenshot use only - * - * @param pathStr path of symbol storage directory - */ - public void setSymbolStorageDirectoryTextOnly(String pathStr) { - symbolServerConfigPanel.setSymbolStorageDirectoryTextOnly(pathStr); - } - - /** - * For screenshot use only - * - * @param symbolServers list of symbol servers - */ - public void setSymbolServers(List symbolServers) { - symbolServerConfigPanel.setSymbolServers(symbolServers); - } - - /** - * For screenshot use only - */ - public void pushAddLocationBution() { - symbolServerConfigPanel.pushAddLocationButton(); - } - private void setSelectedPdbFile(SymbolFileLocation symbolFileLocation) { this.selectedSymbolFile = symbolFileLocation; + setPdbLocationValue(symbolFileLocation, getLocalSymbolFile(symbolFileLocation)); } /** @@ -247,6 +202,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Public only for screenshot usage, treat as private otherwise. * * @param results list of {@link SymbolFileLocation}s to add to results + * @param findOptions the options used to search */ public void setSearchResults(List results, Set findOptions) { lastSearchOptions = findOptions; @@ -304,13 +260,11 @@ public class LoadPdbDialog extends DialogComponentProvider { private void updateButtonEnablement() { boolean hasLocation = selectedSymbolFile != null; + boolean hasGoodService = symbolServerService.isValid(); loadPdbButton.setEnabled(hasLocation); - } - - private void setSymbolServerService(SymbolServerService symbolServerService) { - this.symbolServerService = symbolServerService; - symbolFilePanel.setEnablement(symbolServerService != null); - updateStatusText(); + configButton.setIcon(hasGoodService ? null : MATCH_BAD_ICON); + configButton.setToolTipText(hasGoodService ? null : "Missing configuration"); + symbolFilePanel.setEnablement(hasGoodService); } private SymbolFileInfo getCurrentSymbolFileInfo() { @@ -322,9 +276,6 @@ public class LoadPdbDialog extends DialogComponentProvider { } private void searchForPdbs(boolean allowRemote) { - if (symbolServerService == null || !symbolServerService.isValid()) { - return; - } if (pdbAgeTextField.getText().isBlank() || pdbAgeTextField.getValue() > NumericUtilities.MAX_UNSIGNED_INT32_AS_LONG) { Msg.showWarn(this, null, "Bad PDB Age", "Invalid PDB Age value"); @@ -347,11 +298,12 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolServerService.find(symbolFileInfo, findOptions, monitor); Swing.runLater(() -> { setSearchResults(results, findOptions); - if (results.size() == 1) { + if (!results.isEmpty()) { selectRowByLocation(results.get(0)); } updateStatusText(); updateButtonEnablement(); + updateParserOptionEnablement(true); }); } catch (CancelledException e1) { @@ -364,17 +316,15 @@ public class LoadPdbDialog extends DialogComponentProvider { private void build() { buildSymbolFilePanel(); - buildSSConfigPanel(); buildPdbLocationPanel(); buildProgramPdbPanel(); buildParserOptionsPanel(); setHelpLocation(new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "Load PDB File")); addStatusTextSupplier(() -> lastSearchOptions != null && advancedToggleButton.isSelected() - ? symbolServerConfigPanel.getSymbolServerWarnings() + ? SymbolServerPanel.getSymbolServerWarnings(symbolServerService.getSymbolServers()) : null); addStatusTextSupplier(this::getSelectedPdbNoticeText); - addStatusTextSupplier(this::getConfigChangedWarning); addStatusTextSupplier(this::getAllowRemoteWarning); addStatusTextSupplier(this::getFoundCountInfo); @@ -386,11 +336,6 @@ public class LoadPdbDialog extends DialogComponentProvider { // later dialogShow() will be called } - private void buildSSConfigPanel() { - symbolServerConfigPanel = - new SymbolServerPanel(this::setSymbolServerService, symbolServerInstanceCreatorContext); - } - private void buildSymbolFilePanel() { // panel will be added in layoutAdvanced() symbolFilePanel = new SymbolFilePanel(this::searchForPdbs); @@ -398,7 +343,7 @@ public class LoadPdbDialog extends DialogComponentProvider { symbolFilePanel.getTable() .getSelectionModel() .addListSelectionListener(e -> updateSelectedRow()); - symbolFilePanel.addMouseListener(new GMouseListenerAdapter() { + symbolFilePanel.getTable().addMouseListener(new GMouseListenerAdapter() { @Override public void doubleClickTriggered(MouseEvent e) { if (loadPdbButton.isEnabled()) { @@ -618,6 +563,17 @@ public class LoadPdbDialog extends DialogComponentProvider { addCancelButton(); setDefaultButton(cancelButton); + configButton = new JButton("Config..."); + configButton.addActionListener(e -> { + if (ConfigPdbDialog.showSymbolServerConfig()) { + updateSymbolServerServiceInstanceFromPreferences(); + updateButtonEnablement(); + updateStatusText(); + searchForPdbs(false); + } + }); + addButton(configButton); + advancedToggleButton = new JToggleButton("Advanced >>"); advancedToggleButton.addActionListener(e -> toggleAdvancedSearch()); buttonPanel.add(advancedToggleButton); @@ -625,7 +581,7 @@ public class LoadPdbDialog extends DialogComponentProvider { private void prepareSelectedSymbolFileAndClose(TaskMonitor monitor) { try { - if (selectedSymbolFile != null && symbolServerService != null) { + if (selectedSymbolFile != null) { selectedSymbolFile = symbolServerService.getLocalSymbolFileLocation(selectedSymbolFile, monitor); } @@ -640,17 +596,8 @@ public class LoadPdbDialog extends DialogComponentProvider { } } - private StatusText getConfigChangedWarning() { - return advancedToggleButton.isSelected() && symbolServerConfigPanel.isConfigChanged() - ? new StatusText( - "Symbol Server Search Config Changed. Click \"Save Configuration\" button to save.", - MessageType.INFO, false) - : null; - } - private StatusText getAllowRemoteWarning() { - int remoteSymbolServerCount = - symbolServerService != null ? symbolServerService.getRemoteSymbolServerCount() : 0; + int remoteSymbolServerCount = symbolServerService.getRemoteSymbolServerCount(); return lastSearchOptions != null && advancedToggleButton.isSelected() && remoteSymbolServerCount != 0 && !lastSearchOptions.contains(FindOption.ALLOW_REMOTE) ? new StatusText( @@ -681,31 +628,21 @@ public class LoadPdbDialog extends DialogComponentProvider { overridePdbAgeCheckBox.setVisible(isAdvanced); overridePdbPathCheckBox.setVisible(isAdvanced); overridePdbUniqueIdCheckBox.setVisible(isAdvanced); - setPdbLocationValue(null, null); if (isAdvanced) { - if (symbolServerService == null || !symbolServerService.isValid()) { - setSelectedPdbFile(null); - } layoutAdvanced(); } else { - if (selectedSymbolFile != null) { - File localSymbolFile = getLocalSymbolFile(selectedSymbolFile); - if (localSymbolFile != null) { - setPdbLocationValue(selectedSymbolFile, localSymbolFile); - } - } - else { - setSelectedPdbFile(null); - } layoutSimple(); } updateStatusText(); updateButtonEnablement(); updateParserOptionEnablement(false); - repack(); + if (isAdvanced && !hasShownAdvanced) { + hasShownAdvanced = true; + repack(); + } } private void layoutSimple() { @@ -720,21 +657,17 @@ public class LoadPdbDialog extends DialogComponentProvider { overrideWorkPanel(panel); } - private void overrideWorkPanel(JComponent workComp) { + private void overrideWorkPanel(JComponent newWorkComp) { if (this.workComp != null && this.workComp.getParent() != null) { this.workComp.getParent().remove(this.workComp); } - this.workComp = workComp; - addWorkPanel(workComp); + this.workComp = newWorkComp; + addWorkPanel(newWorkComp); } private void layoutAdvanced() { - Box topPanel = Box.createHorizontalBox(); - topPanel.add(programPdbPanel); - topPanel.add(symbolServerConfigPanel); - JPanel mainPanel = new JPanel(new BorderLayout()); - mainPanel.add(topPanel, BorderLayout.NORTH); + mainPanel.add(programPdbPanel, BorderLayout.NORTH); mainPanel.add(symbolFilePanel, BorderLayout.CENTER); mainPanel.add(parserOptionsPanel, BorderLayout.SOUTH); diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java index 2dc709a66f..dfca92f5d0 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolFilePanel.java @@ -117,7 +117,7 @@ class SymbolFilePanel extends JPanel { private JPanel buildWelcomePanel() { welcomePanel = new JPanel(); welcomePanel.add(new GHtmlLabel( - " Local Symbol Storage location must be set first!")); + " Configuration must be set first!")); welcomePanel.setPreferredSize(tablePanel.getPreferredSize()); return welcomePanel; diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java index 985ffc1da6..423f6e0325 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java @@ -52,7 +52,7 @@ import utilities.util.FileUtilities; class SymbolServerPanel extends JPanel { private static final String MS_SYMBOLSERVER_ENVVAR = "_NT_SYMBOL_PATH"; - private List knownSymbolServers = + private static List knownSymbolServers = WellKnownSymbolServerLocation.loadAll(); private SymbolStore localSymbolStore; @@ -297,23 +297,6 @@ class SymbolServerPanel extends JPanel { updateLayout(hasLocalSymbolStore); } - StatusText getSymbolServerWarnings() { - Map warningsByLocation = new HashMap<>(); - for (WellKnownSymbolServerLocation ssloc : knownSymbolServers) { - if (ssloc.getWarning() != null && !ssloc.getWarning().isBlank()) { - warningsByLocation.put(ssloc.getLocation(), ssloc.getWarning()); - } - } - String warning = tableModel.getDataSource() - .stream() - .map(row -> warningsByLocation.get(row.getSymbolServer().getName())) - .filter(Objects::nonNull) - .distinct() - .collect(Collectors.joining("
\n")); - - return !warning.isEmpty() ? new StatusText(warning, MessageType.WARNING, false) : null; - } - private void setSymbolStorageLocation(File symbolStorageDir, boolean allowGUIPrompt) { if (symbolStorageDir == null) { return; @@ -601,5 +584,22 @@ class SymbolServerPanel extends JPanel { return button; } + + static StatusText getSymbolServerWarnings(ListsymbolServers) { + Map warningsByLocation = new HashMap<>(); + for (WellKnownSymbolServerLocation ssloc : knownSymbolServers) { + if (ssloc.getWarning() != null && !ssloc.getWarning().isBlank()) { + warningsByLocation.put(ssloc.getLocation(), ssloc.getWarning()); + } + } + String warning = symbolServers + .stream() + .map(symbolServer -> warningsByLocation.get(symbolServer.getName())) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.joining("
\n")); + + return !warning.isEmpty() ? new StatusText(warning, MessageType.WARNING, false) : null; + } } diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java index a59dd267c3..280d9d7c78 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/PdbScreenShots.java @@ -69,11 +69,30 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); showDialogWithoutBlocking(tool, configPdbDialog); waitForSwing(); - captureDialog(ConfigPdbDialog.class); + captureDialog(ConfigPdbDialog.class, 410, 280); } @Test - public void testLoadPdb_Initial_Screenshot() throws IOException { + public void testSymbolServerConfig_Configured() throws IOException { + File localSymbolStore1Root = new File(temporaryDir, "symbols"); + LocalSymbolStore.create(localSymbolStore1Root, 1); + LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root); + SameDirSymbolStore sameDirSymbolStore = new SameDirSymbolStore(null); + ListsymbolServers = List.of(sameDirSymbolStore, + new HttpSymbolServer(URI.create("https://msdl.microsoft.com/download/symbols/"))); + SymbolServerService symbolServerService = + new SymbolServerService(localSymbolStore1, symbolServers); + PdbPlugin.saveSymbolServerServiceConfig(symbolServerService); + + ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); + configPdbDialog.setSymbolServerService("/home/user/symbols", symbolServers); + showDialogWithoutBlocking(tool, configPdbDialog); + waitForSwing(); + captureDialog(ConfigPdbDialog.class, 410, 280); + } + + @Test + public void testLoadPdb_Initial_Screenshot() { LoadPdbDialog loadPdbDialog = new LoadPdbDialog(program); showDialogWithoutBlocking(tool, loadPdbDialog); captureDialog(loadPdbDialog); @@ -84,32 +103,30 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { public void testSymbolServerConfig_AddButtonMenu() throws IOException { File localSymbolStore1Root = new File(temporaryDir, "symbols"); LocalSymbolStore.create(localSymbolStore1Root, 1); - LocalSymbolStore localSymbolStore1 = - new LocalSymbolStoreWithFakePath(localSymbolStore1Root, "/home/user/symbols"); + LocalSymbolStore localSymbolStore1 = new LocalSymbolStore(localSymbolStore1Root); SymbolServerService symbolServerService = new SymbolServerService(localSymbolStore1, List.of()); PdbPlugin.saveSymbolServerServiceConfig(symbolServerService); - LoadPdbDialog choosePdbDialog = new LoadPdbDialog(program); - showDialogWithoutBlocking(tool, choosePdbDialog); + ConfigPdbDialog configPdbDialog = new ConfigPdbDialog(); + showDialogWithoutBlocking(tool, configPdbDialog); waitForSwing(); - pressButtonByText(choosePdbDialog, "Advanced >>"); runSwing(() -> { - choosePdbDialog.pushAddLocationBution(); + configPdbDialog.pushAddLocationButton(); }); waitForSwing(); captureMenu(); } @Test - public void testLoadPdb_Advanced_NeedsConfig() throws IOException { + public void testLoadPdb_Advanced_NeedsConfig() { PdbPlugin.saveSymbolServerServiceConfig(null); LoadPdbDialog choosePdbDialog = new LoadPdbDialog(program); showDialogWithoutBlocking(tool, choosePdbDialog); waitForSwing(); pressButtonByText(choosePdbDialog, "Advanced >>"); waitForSwing(); - captureDialog(LoadPdbDialog.class); + captureDialog(LoadPdbDialog.class, 600, 500); pressButtonByText(choosePdbDialog, "Cancel"); } @@ -140,19 +157,15 @@ public class PdbScreenShots extends GhidraScreenShotGenerator { new SymbolFileLocation("HelloWorld.pdb/" + GUID1_STR + "2/HelloWorld.pdb", localSymbolStore1, SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 2)), new SymbolFileLocation("HelloWorld.pdb", sameDirSymbolStoreWithFakePath, - SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1)), - new SymbolFileLocation("HelloWorld_ver2.pdb", sameDirSymbolStoreWithFakePath, - SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 2))); + SymbolFileInfo.fromValues("HelloWorld.pdb", GUID1_STR, 1))); Set findOptions = FindOption.of(FindOption.ALLOW_REMOTE, FindOption.ANY_AGE); runSwing(() -> { loadPdbDialog.setSearchOptions(findOptions); - loadPdbDialog.setSymbolServers(symbolServers); - loadPdbDialog.setSymbolStorageDirectoryTextOnly("/home/user/symbols"); loadPdbDialog.setSearchResults(symbolFileLocations, findOptions); loadPdbDialog.selectRowByLocation(symbolFileLocations.get(0)); }); waitForSwing(); - captureDialog(LoadPdbDialog.class); + captureDialog(LoadPdbDialog.class, 600, 600); pressButtonByText(loadPdbDialog, "Cancel"); }