mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Task Launcher - updated timeout feature to ignore interruptions
This commit is contained in:
parent
fb2a4a0363
commit
2cf9f7dded
11 changed files with 240 additions and 344 deletions
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.processors.sleigh;
|
||||
|
||||
import static utilities.util.FileUtilities.existsAndIsCaseDependent;
|
||||
import static utilities.util.FileUtilities.*;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
@ -99,6 +99,11 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
return getNewSleigh(languageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLanguageLoaded(LanguageID languageId) {
|
||||
return languages.get(languageId) != null;
|
||||
}
|
||||
|
||||
private Language getNewSleigh(LanguageID languageId) {
|
||||
SleighLanguageDescription description = descriptions.get(languageId);
|
||||
SleighLanguage lang = languages.get(languageId);
|
||||
|
@ -108,31 +113,31 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
languages.put(languageId, lang);
|
||||
}
|
||||
catch (SleighException e) {
|
||||
Msg.showError(this, null, "Error", "Can't read language spec " +
|
||||
description.getSlaFile().getAbsolutePath(), e);
|
||||
Msg.showError(this, null, "Error",
|
||||
"Can't read language spec " + description.getSlaFile().getAbsolutePath(), e);
|
||||
throw e;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Msg.showError(this, null, "Error", "Can't read language spec " +
|
||||
description.getSlaFile().getAbsolutePath(), e);
|
||||
Msg.showError(this, null, "Error",
|
||||
"Can't read language spec " + description.getSlaFile().getAbsolutePath(), e);
|
||||
throw new SleighException(
|
||||
"File not found - language probably did not compile properly", e);
|
||||
}
|
||||
catch (UnknownInstructionException e) {
|
||||
Msg.showError(this, null, "Error", "Can't read language spec " +
|
||||
description.getSlaFile().getAbsolutePath(), e);
|
||||
Msg.showError(this, null, "Error",
|
||||
"Can't read language spec " + description.getSlaFile().getAbsolutePath(), e);
|
||||
throw new SleighException(
|
||||
"Unknown instruction - language probably did not compile properly", e);
|
||||
}
|
||||
catch (SAXException e) {
|
||||
Msg.showError(this, null, "Error", "Can't read language spec " +
|
||||
description.getSlaFile().getAbsolutePath(), e);
|
||||
Msg.showError(this, null, "Error",
|
||||
"Can't read language spec " + description.getSlaFile().getAbsolutePath(), e);
|
||||
throw new SleighException(
|
||||
"SAXException - language probably did not compile properly", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "Error", "Can't read language spec " +
|
||||
description.getSlaFile().getAbsolutePath(), e);
|
||||
Msg.showError(this, null, "Error",
|
||||
"Can't read language spec " + description.getSlaFile().getAbsolutePath(), e);
|
||||
throw new SleighException(
|
||||
"IOException - language probably did not compile properly", e);
|
||||
}
|
||||
|
@ -162,7 +167,8 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
|
||||
@Override
|
||||
public void fatalError(SAXParseException exception) throws SAXException {
|
||||
Msg.error(SleighLanguageProvider.this, "Fatal error parsing " + specFile, exception);
|
||||
Msg.error(SleighLanguageProvider.this, "Fatal error parsing " + specFile,
|
||||
exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -256,8 +262,8 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
truncatedSpaceMap = new HashMap<String, Integer>();
|
||||
}
|
||||
if (truncatedSpaceMap.put(spaceName, truncatedSize) != null) {
|
||||
throw new SleighException("truncated space '" + spaceName +
|
||||
"' alread specified");
|
||||
throw new SleighException(
|
||||
"truncated space '" + spaceName + "' alread specified");
|
||||
}
|
||||
parser.end(element);
|
||||
}
|
||||
|
@ -267,15 +273,15 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
final String compilerSpecName = compiler.getAttribute("name");
|
||||
final String compilerSpecFilename = compiler.getAttribute("spec");
|
||||
final ResourceFile compilerSpecFile =
|
||||
findFile(parentDirectory, compilerSpecFilename, ".cspec");
|
||||
findFile(parentDirectory, compilerSpecFilename, ".cspec");
|
||||
FileResolutionResult result = existsAndIsCaseDependent(compilerSpecFile);
|
||||
if (!result.isOk()) {
|
||||
throw new SleighException("cspec file " + compilerSpecFile +
|
||||
" is not properly case dependent: " + result.getMessage());
|
||||
}
|
||||
final SleighCompilerSpecDescription sleighCompilerSpecDescription =
|
||||
new SleighCompilerSpecDescription(compilerSpecID, compilerSpecName,
|
||||
compilerSpecFile);
|
||||
new SleighCompilerSpecDescription(compilerSpecID, compilerSpecName,
|
||||
compilerSpecFile);
|
||||
compilerSpecs.add(sleighCompilerSpecDescription);
|
||||
parser.end(compiler);
|
||||
}
|
||||
|
@ -301,11 +307,10 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
|
||||
// skip the language end tag
|
||||
parser.end(languageEnter);
|
||||
description =
|
||||
new SleighLanguageDescription(id, descriptionText,
|
||||
Processor.findOrPossiblyCreateProcessor(processorName), endian,
|
||||
instructionEndian, size, variant, version, minorVersion, deprecated,
|
||||
truncatedSpaceMap, compilerSpecs, externalNameMap);
|
||||
description = new SleighLanguageDescription(id, descriptionText,
|
||||
Processor.findOrPossiblyCreateProcessor(processorName), endian, instructionEndian,
|
||||
size, variant, version, minorVersion, deprecated, truncatedSpaceMap, compilerSpecs,
|
||||
externalNameMap);
|
||||
final ResourceFile defsFile = new ResourceFile(parentDirectory, ldefs);
|
||||
FileResolutionResult result = existsAndIsCaseDependent(defsFile);
|
||||
if (!result.isOk()) {
|
||||
|
@ -337,8 +342,7 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
|
||||
String slaspecfilename = slabase + ".slaspec";
|
||||
|
||||
ResourceFile slaspecFile =
|
||||
findFile(parentDirectory, slaspecfilename, ".slaspec");
|
||||
ResourceFile slaspecFile = findFile(parentDirectory, slaspecfilename, ".slaspec");
|
||||
result = existsAndIsCaseDependent(slaspecFile);
|
||||
if (!result.isOk()) {
|
||||
throw new SleighException("sla file source " + slaspecFile +
|
||||
|
|
|
@ -33,7 +33,7 @@ public interface LanguageProvider extends ExtensionPoint {
|
|||
* @return the {@link Language} with the given name
|
||||
*/
|
||||
Language getLanguage(LanguageID languageId);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of language descriptions provided by this provider
|
||||
*/
|
||||
|
@ -45,4 +45,11 @@ public interface LanguageProvider extends ExtensionPoint {
|
|||
*/
|
||||
boolean hadLoadFailure();
|
||||
|
||||
/**
|
||||
* Returns true if the given language has been successfully loaded
|
||||
*
|
||||
* @param languageId the name of the language to be retrieved
|
||||
* @return true if the given language has been successfully loaded
|
||||
*/
|
||||
boolean isLanguageLoaded(LanguageID languageId);
|
||||
}
|
||||
|
|
|
@ -102,68 +102,42 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getLanguage(ghidra.program.model.lang.LanguageID)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public Language getLanguage(LanguageID languageID) throws LanguageNotFoundException {
|
||||
LanguageInfo info = languageMap.get(languageID);
|
||||
if (info == null) {
|
||||
throw new LanguageNotFoundException(languageID);
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
TaskBuilder.withRunnable(monitor -> {
|
||||
info.getLanguage(); // load and cache
|
||||
})
|
||||
.setTitle("Loading language '" + languageID + "'")
|
||||
.setCanCancel(false)
|
||||
.setHasProgress(false)
|
||||
.launchModal()
|
||||
;
|
||||
//@formatter:on
|
||||
|
||||
return info.getLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getLanguageDescription(ghidra.program.model.lang.LanguageID)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public LanguageDescription getLanguageDescription(LanguageID languageID)
|
||||
throws LanguageNotFoundException {
|
||||
LanguageInfo info = languageMap.get(languageID);
|
||||
if (info == null) {
|
||||
throw new LanguageNotFoundException(languageID);
|
||||
}
|
||||
return info.ld;
|
||||
return info.description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getLanguageDescriptions(boolean)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public List<LanguageDescription> getLanguageDescriptions(boolean includeDeprecatedLanguages) {
|
||||
List<LanguageDescription> languageDescriptions = new ArrayList<>();
|
||||
for (LanguageInfo info : languageInfos) {
|
||||
if (includeDeprecatedLanguages || !info.ld.isDeprecated()) {
|
||||
languageDescriptions.add(info.ld);
|
||||
if (includeDeprecatedLanguages || !info.description.isDeprecated()) {
|
||||
languageDescriptions.add(info.description);
|
||||
}
|
||||
}
|
||||
return languageDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getLanguageDescriptions(ghidra.program.model.lang.Processor,
|
||||
* ghidra.program.model.lang.Endian, java.lang.Integer,
|
||||
* java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public List<LanguageDescription> getLanguageDescriptions(Processor processor, Endian endianess,
|
||||
Integer size, String variant) {
|
||||
List<LanguageDescription> languageDescriptions = new ArrayList<>();
|
||||
for (LanguageInfo info : languageInfos) {
|
||||
LanguageDescription description = info.ld;
|
||||
LanguageDescription description = info.description;
|
||||
if (processor != null && processor != description.getProcessor()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -206,7 +180,7 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
|
||||
List<LanguageDescription> languageDescriptions = new ArrayList<>();
|
||||
for (LanguageInfo info : languageInfos) {
|
||||
LanguageDescription description = info.ld;
|
||||
LanguageDescription description = info.description;
|
||||
|
||||
if (!languageMatchesExternalProcessor(description, externalProcessorName,
|
||||
externalTool)) {
|
||||
|
@ -300,16 +274,13 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getLanguageDescriptions(ghidra.program.model.lang.Processor)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public List<LanguageDescription> getLanguageDescriptions(Processor processor) {
|
||||
ArrayList<LanguageDescription> list = new ArrayList<>();
|
||||
|
||||
for (LanguageInfo info : languageInfos) {
|
||||
if (info.ld.getProcessor().equals(processor)) {
|
||||
list.add(info.ld);
|
||||
if (info.description.getProcessor().equals(processor)) {
|
||||
list.add(info.description);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
@ -350,16 +321,13 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.lang.LanguageService#getDefaultLanguage(ghidra.program.model.lang.Processor)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public Language getDefaultLanguage(Processor processor) throws LanguageNotFoundException {
|
||||
if (processor == null) {
|
||||
throw new IllegalArgumentException("processor == null not allowed");
|
||||
}
|
||||
for (LanguageInfo info : languageInfos) {
|
||||
if (info.ld.getProcessor().equals(processor)) {
|
||||
if (info.description.getProcessor().equals(processor)) {
|
||||
long start = System.currentTimeMillis();
|
||||
Language language = info.getLanguage();
|
||||
log.debug("getDefaultLanguage(" + language.getLanguageID() + ") took " +
|
||||
|
@ -385,7 +353,7 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
continue;
|
||||
}
|
||||
languageInfos.add(info);
|
||||
LanguageID id = info.ld.getLanguageID();
|
||||
LanguageID id = info.description.getLanguageID();
|
||||
if (languageMap.containsKey(id)) {
|
||||
throw new IllegalStateException("Duplicate language ID encountered: " + id);
|
||||
}
|
||||
|
@ -393,22 +361,42 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
class LanguageInfo {
|
||||
LanguageDescription ld;
|
||||
LanguageProvider lp;
|
||||
private class LanguageInfo {
|
||||
|
||||
private LanguageProvider provider;
|
||||
LanguageDescription description;
|
||||
|
||||
LanguageInfo(LanguageDescription ld, LanguageProvider lp) {
|
||||
this.ld = ld;
|
||||
this.lp = lp;
|
||||
this.description = ld;
|
||||
this.provider = lp;
|
||||
}
|
||||
|
||||
Language getLanguage() {
|
||||
return lp.getLanguage(ld.getLanguageID());
|
||||
// synchronized to prevent multiple clients from trying to load the language at once
|
||||
synchronized Language getLanguage() {
|
||||
|
||||
LanguageID id = description.getLanguageID();
|
||||
if (provider.isLanguageLoaded(id)) {
|
||||
// already loaded; no need to create a task
|
||||
return provider.getLanguage(id);
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
TaskBuilder.withRunnable(monitor -> {
|
||||
provider.getLanguage(id); // load and cache
|
||||
})
|
||||
.setTitle("Loading language '" + id + "'")
|
||||
.setCanCancel(false)
|
||||
.setHasProgress(false)
|
||||
.launchModal()
|
||||
;
|
||||
//@formatter:on
|
||||
|
||||
return provider.getLanguage(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ld.getLanguageID().getIdAsString();
|
||||
return description.getLanguageID().getIdAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -417,19 +405,16 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
return false;
|
||||
}
|
||||
LanguageInfo otherInfo = (LanguageInfo) obj;
|
||||
return ld.getLanguageID().equals(otherInfo.ld.getLanguageID());
|
||||
return description.getLanguageID().equals(otherInfo.description.getLanguageID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ld.getLanguageID().hashCode();
|
||||
return description.getLanguageID().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
|
||||
*/
|
||||
@Override
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
// NOTE: this is only intended to pickup new language providers
|
||||
// which is not really supported with the introduction of Sleigh.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue