mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch
'origin/GP-5716_ghidranoob_HelpAboutSpecFiles--SQUASHED' (Closes #8163)
This commit is contained in:
commit
e40f817886
1 changed files with 113 additions and 6 deletions
|
@ -15,7 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.help;
|
package ghidra.app.plugin.core.help;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
|
@ -34,12 +36,15 @@ import ghidra.framework.main.datatable.ProjectDataContext;
|
||||||
import ghidra.framework.model.DomainFile;
|
import ghidra.framework.model.DomainFile;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
import ghidra.program.database.ProgramDB;
|
||||||
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.DefaultLanguageService;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a pop-up dialog containing information about the Domain Object
|
* Display a pop-up dialog containing information about the Domain Object that is currently open in
|
||||||
* that is currently open in the tool.
|
* the tool.
|
||||||
*/
|
*/
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -72,6 +77,106 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record LcspAndVersion(Language language, CompilerSpec compilerSpec, Integer languageVersion,
|
||||||
|
Integer languageMinorVersion) {
|
||||||
|
public static final Pattern LANG_PAT =
|
||||||
|
Pattern.compile("(?<id>\\S+) \\((?<major>\\d+)\\.(?<minor>\\d+)\\)");
|
||||||
|
|
||||||
|
static Language tryLang(String languageID) {
|
||||||
|
LanguageService langServ = DefaultLanguageService.getLanguageService();
|
||||||
|
try {
|
||||||
|
return langServ.getLanguage(new LanguageID(languageID));
|
||||||
|
}
|
||||||
|
catch (LanguageNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Integer tryInt(String i) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(i);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CompilerSpec tryCompiler(Language language, String compilerSpecID) {
|
||||||
|
try {
|
||||||
|
return language.getCompilerSpecByID(new CompilerSpecID(compilerSpecID));
|
||||||
|
}
|
||||||
|
catch (CompilerSpecNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ProgramDB#getMetadata()
|
||||||
|
* @param metadata the metadata
|
||||||
|
* @return the parsed language, compiler spec, and language version
|
||||||
|
*/
|
||||||
|
public static LcspAndVersion fromMetadata(Map<String, String> metadata) {
|
||||||
|
String languageInfo = metadata.get("Language ID");
|
||||||
|
if (languageInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher matcher = LANG_PAT.matcher(languageInfo);
|
||||||
|
Language language;
|
||||||
|
Integer languageVersion;
|
||||||
|
Integer languageMinorVersion;
|
||||||
|
if (matcher.matches()) {
|
||||||
|
language = tryLang(matcher.group("id"));
|
||||||
|
languageVersion = tryInt(matcher.group("major"));
|
||||||
|
languageMinorVersion = tryInt(matcher.group("minor"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
language = tryLang(languageInfo);
|
||||||
|
languageVersion = null;
|
||||||
|
languageMinorVersion = null;
|
||||||
|
}
|
||||||
|
if (language == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String compilerInfo = metadata.get("Compiler ID");
|
||||||
|
if (compilerInfo == null) {
|
||||||
|
return new LcspAndVersion(language, null, languageVersion, languageMinorVersion);
|
||||||
|
}
|
||||||
|
CompilerSpec compilerSpec = tryCompiler(language, compilerInfo);
|
||||||
|
return new LcspAndVersion(language, compilerSpec, languageVersion,
|
||||||
|
languageMinorVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMismatch() {
|
||||||
|
return !Objects.equals(language.getVersion(), languageVersion) ||
|
||||||
|
!Objects.equals(language.getMinorVersion(), languageMinorVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersionDisplay() {
|
||||||
|
if (language == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return " (%d.%d)".formatted(language.getVersion(), language.getMinorVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLanguageFileInfo(Map<String, String> metadata) {
|
||||||
|
LcspAndVersion lav = LcspAndVersion.fromMetadata(metadata);
|
||||||
|
if (lav == null || lav.language == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lav.language.getLanguageDescription() instanceof SleighLanguageDescription lDesc) {
|
||||||
|
metadata.put("Language Spec",
|
||||||
|
lDesc.getDefsFile() + (lav.isMismatch() ? lav.getVersionDisplay() : ""));
|
||||||
|
metadata.put("Processor Spec", lDesc.getSpecFile().getAbsolutePath());
|
||||||
|
metadata.put("Sleigh Spec", lDesc.getSlaFile().getAbsolutePath() + "spec");
|
||||||
|
}
|
||||||
|
if (lav.compilerSpec != null) {
|
||||||
|
metadata.put("Compiler Spec",
|
||||||
|
lav.compilerSpec.getCompilerSpecDescription().getSource());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setupActions() {
|
private void setupActions() {
|
||||||
if (tool instanceof FrontEndTool) {
|
if (tool instanceof FrontEndTool) {
|
||||||
aboutAction = new FrontendProjectTreeAction(ACTION_NAME, PLUGIN_NAME) {
|
aboutAction = new FrontendProjectTreeAction(ACTION_NAME, PLUGIN_NAME) {
|
||||||
|
@ -79,8 +184,8 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
|
||||||
@Override
|
@Override
|
||||||
protected void actionPerformed(ProjectDataContext context) {
|
protected void actionPerformed(ProjectDataContext context) {
|
||||||
DomainFile domainFile = context.getSelectedFiles().get(0);
|
DomainFile domainFile = context.getSelectedFiles().get(0);
|
||||||
Map<String, String> metadata = domainFile.getMetadata();
|
Map<String, String> metadata = new LinkedHashMap<>(domainFile.getMetadata());
|
||||||
|
addLanguageFileInfo(metadata);
|
||||||
showAbout(domainFile, metadata);
|
showAbout(domainFile, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +211,9 @@ public class AboutProgramPlugin extends Plugin implements ApplicationLevelPlugin
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ProgramActionContext context) {
|
public void actionPerformed(ProgramActionContext context) {
|
||||||
Program program = context.getProgram();
|
Program program = context.getProgram();
|
||||||
showAbout(program.getDomainFile(), program.getMetadata());
|
Map<String, String> metadata = new LinkedHashMap<>(program.getMetadata());
|
||||||
|
addLanguageFileInfo(metadata);
|
||||||
|
showAbout(program.getDomainFile(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue