mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-1 Hard-wired DefaultLanguageService into SleighLanguageProvider and
eliminated single-ldef usage.
This commit is contained in:
parent
1a99e2518d
commit
12cb9010c5
13 changed files with 77 additions and 136 deletions
|
@ -62,12 +62,26 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
|
||||
public final static String LANGUAGE_DIR_NAME = "languages";
|
||||
|
||||
public SleighLanguageProvider() throws Exception {
|
||||
createLanguages();
|
||||
private static SleighLanguageProvider instance; // sleigh language provider instance (singleton)
|
||||
|
||||
public static synchronized SleighLanguageProvider getSleighLanguageProvider() {
|
||||
if (instance == null) {
|
||||
instance = new SleighLanguageProvider();
|
||||
try {
|
||||
instance.createLanguages();
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(SleighLanguageProvider.class,
|
||||
"Sleigh language provider initiailization failed", e);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public SleighLanguageProvider(ResourceFile ldefsFile) throws Exception {
|
||||
createLanguages(ldefsFile);
|
||||
/**
|
||||
* Construct sleigh language provider (singleton)
|
||||
*/
|
||||
private SleighLanguageProvider() {
|
||||
}
|
||||
|
||||
private void createLanguages() throws Exception {
|
||||
|
@ -96,7 +110,11 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
|
||||
@Override
|
||||
public Language getLanguage(LanguageID languageId) {
|
||||
return getNewSleigh(languageId);
|
||||
Language language = languages.get(languageId);
|
||||
if (language == null) {
|
||||
language = getNewSleigh(languageId);
|
||||
}
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,7 +122,7 @@ public class SleighLanguageProvider implements LanguageProvider {
|
|||
return languages.get(languageId) != null;
|
||||
}
|
||||
|
||||
private Language getNewSleigh(LanguageID languageId) {
|
||||
private SleighLanguage getNewSleigh(LanguageID languageId) {
|
||||
SleighLanguageDescription description = descriptions.get(languageId);
|
||||
SleighLanguage lang = languages.get(languageId);
|
||||
if (lang == null) {
|
||||
|
|
|
@ -30,7 +30,8 @@ public interface LanguageProvider extends ExtensionPoint {
|
|||
* Returns the language with the given name or null if no language has that name
|
||||
*
|
||||
* @param languageId the name of the language to be retrieved
|
||||
* @return the {@link Language} with the given name
|
||||
* @return the {@link Language} with the given name or null if not found
|
||||
* @throws RuntimeException if language instantiation error occurs
|
||||
*/
|
||||
Language getLanguage(LanguageID languageId);
|
||||
|
||||
|
|
|
@ -17,28 +17,22 @@ package ghidra.program.util;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguageProvider;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
import ghidra.util.task.TaskBuilder;
|
||||
|
||||
/**
|
||||
* Default Language service used gather up all the languages that were found
|
||||
* during the class search (search was for language providers)
|
||||
*/
|
||||
public class DefaultLanguageService implements LanguageService, ChangeListener {
|
||||
public class DefaultLanguageService implements LanguageService {
|
||||
private static final Logger log = LogManager.getLogger(DefaultLanguageService.class);
|
||||
|
||||
private List<LanguageInfo> languageInfos = new ArrayList<>();
|
||||
private HashMap<LanguageID, LanguageInfo> languageMap = new HashMap<>();
|
||||
private boolean searchCompleted = false;
|
||||
|
||||
private static DefaultLanguageService languageService;
|
||||
|
||||
|
@ -50,59 +44,18 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
if (languageService == null) {
|
||||
languageService = new DefaultLanguageService();
|
||||
}
|
||||
else if (!languageService.searchCompleted) {
|
||||
languageService.searchForProviders();
|
||||
}
|
||||
return languageService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the single instance of the DefaultLanguageService. If not already
|
||||
* instantiated in the default mode, the factory will be lazy and limit
|
||||
* it set of languages to those defined by the specified Sleigh language definition
|
||||
* file (*.ldefs) or those provided by subsequent calls to this method.
|
||||
* @param sleighLdefsFile sleigh language definition file
|
||||
* @return language factory instance
|
||||
* @throws Exception if an error occurs while parsing the specified definition file
|
||||
*/
|
||||
public static synchronized LanguageService getLanguageService(ResourceFile sleighLdefsFile)
|
||||
throws Exception {
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider(sleighLdefsFile);
|
||||
if (languageService == null) {
|
||||
languageService = new DefaultLanguageService(provider);
|
||||
}
|
||||
languageService.addLanguages(provider);
|
||||
return languageService;
|
||||
}
|
||||
|
||||
private DefaultLanguageService() {
|
||||
searchForProviders();
|
||||
ClassSearcher.addChangeListener(this);
|
||||
addLanguages(SleighLanguageProvider.getSleighLanguageProvider());
|
||||
}
|
||||
|
||||
private DefaultLanguageService(LanguageProvider provider) {
|
||||
addLanguages(provider);
|
||||
}
|
||||
|
||||
private void searchForProviders() {
|
||||
List<LanguageProvider> languageProviders =
|
||||
ClassSearcher.getInstances(LanguageProvider.class);
|
||||
|
||||
searchCompleted = true;
|
||||
|
||||
//@formatter:off
|
||||
TaskBuilder.withRunnable(monitor -> {
|
||||
processProviders(languageProviders); // load and cache
|
||||
})
|
||||
.setTitle("Language Search")
|
||||
.setCanCancel(false)
|
||||
.setHasProgress(false)
|
||||
.launchModal()
|
||||
;
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Language getLanguage(LanguageID languageID) throws LanguageNotFoundException {
|
||||
LanguageInfo info = languageMap.get(languageID);
|
||||
if (info == null) {
|
||||
|
@ -338,12 +291,6 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
throw new LanguageNotFoundException(processor);
|
||||
}
|
||||
|
||||
private void processProviders(List<LanguageProvider> providers) {
|
||||
for (LanguageProvider provider : providers) {
|
||||
addLanguages(provider);
|
||||
}
|
||||
}
|
||||
|
||||
private void addLanguages(LanguageProvider provider) {
|
||||
LanguageDescription[] lds = provider.getLanguageDescriptions();
|
||||
for (LanguageDescription description : lds) {
|
||||
|
@ -414,10 +361,4 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
@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.
|
||||
searchForProviders();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.assembler.sleigh;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -29,13 +29,15 @@ import ghidra.app.plugin.assembler.sleigh.parse.*;
|
|||
import ghidra.app.plugin.assembler.sleigh.sem.*;
|
||||
import ghidra.app.plugin.assembler.sleigh.tree.AssemblyParseTreeNode;
|
||||
import ghidra.app.plugin.assembler.sleigh.util.DbgTimer;
|
||||
import ghidra.app.plugin.processors.sleigh.*;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighInstructionPrototype;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||
import ghidra.app.util.PseudoInstruction;
|
||||
import ghidra.generic.util.datastruct.TreeSetValuedTreeMap;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOverflowException;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.util.DefaultLanguageService;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.NumericUtilities;
|
||||
|
||||
|
@ -70,8 +72,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
|||
public void setUp() throws Exception {
|
||||
LanguageID langID = getLanguageID();
|
||||
if (!setupLangID.equals(langID.toString())) {
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider();
|
||||
lang = (SleighLanguage) provider.getLanguage(langID);
|
||||
lang = getLanguage(langID);
|
||||
context = new AssemblyDefaultContext(lang);
|
||||
setupLangID = langID.toString();
|
||||
}
|
||||
|
@ -83,6 +84,11 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
|||
//dbg.resetOutputStream(oldOutput).close();
|
||||
}
|
||||
|
||||
private static SleighLanguage getLanguage(LanguageID langID) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return (SleighLanguage) languageService.getLanguage(langID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a collection of parse trees to the debug printer
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.assembler.sleigh;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -72,7 +72,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest {
|
|||
public void setUp() throws Exception {
|
||||
LanguageID langID = getLanguageID();
|
||||
if (!setupLangID.equals(langID.toString())) {
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider();
|
||||
SleighLanguageProvider provider = SleighLanguageProvider.getSleighLanguageProvider();
|
||||
lang = (SleighLanguage) provider.getLanguage(langID);
|
||||
context = new AssemblyDefaultContext(lang);
|
||||
setupLangID = langID.toString();
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.assembler.sleigh;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -25,14 +24,13 @@ import org.junit.*;
|
|||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.plugin.assembler.*;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguageProvider;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.database.util.ProgramTransaction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOverflowException;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.LanguageID;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.DefaultLanguageService;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -44,9 +42,8 @@ public class PublicAPITest extends AbstractGenericTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider();
|
||||
x86 = provider.getLanguage(new LanguageID("x86:LE:64:default"));
|
||||
toy = provider.getLanguage(new LanguageID("Toy:BE:64:default"));
|
||||
x86 = getLanguage("x86:LE:64:default");
|
||||
toy = getLanguage("Toy:BE:64:default");
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -55,6 +52,11 @@ public class PublicAPITest extends AbstractGenericTest {
|
|||
program.release(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static Language getLanguage(String languageName) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return languageService.getLanguage(new LanguageID(languageName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testADD0() throws AssemblySyntaxException, AssemblySemanticException {
|
||||
|
|
|
@ -36,7 +36,8 @@ import ghidra.app.plugin.processors.sleigh.template.ConstructTpl;
|
|||
import ghidra.app.plugin.processors.sleigh.template.HandleTpl;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.ApplicationConfiguration;
|
||||
import ghidra.program.model.lang.LanguageID;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.util.DefaultLanguageService;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.xml.XmlPullParser;
|
||||
import ghidra.xml.XmlPullParserFactory;
|
||||
|
@ -182,6 +183,11 @@ public class SolverTest {
|
|||
AssemblyResolution e = AssemblyResolvedPatterns.fromString("ins:X7:X8", "Test", null);
|
||||
assertEquals(e, res);
|
||||
}
|
||||
|
||||
private static Language getLanguage(String languageName) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return languageService.getLanguage(new LanguageID(languageName));
|
||||
}
|
||||
|
||||
public static Constructor findConstructor(String langId, String subtableName, String patternStr)
|
||||
throws Exception {
|
||||
|
@ -189,7 +195,7 @@ public class SolverTest {
|
|||
Application.initializeApplication(new GhidraApplicationLayout(),
|
||||
new ApplicationConfiguration());
|
||||
}
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider();
|
||||
SleighLanguageProvider provider = SleighLanguageProvider.getSleighLanguageProvider();
|
||||
SleighLanguage lang = (SleighLanguage) provider.getLanguage(new LanguageID(langId));
|
||||
AtomicReference<Constructor> consref = new AtomicReference<>();
|
||||
SleighLanguages.traverseConstructors(lang, new ConstructorEntryVisitor() {
|
||||
|
@ -213,7 +219,7 @@ public class SolverTest {
|
|||
Application.initializeApplication(new GhidraApplicationLayout(),
|
||||
new ApplicationConfiguration());
|
||||
}
|
||||
SleighLanguageProvider provider = new SleighLanguageProvider();
|
||||
SleighLanguageProvider provider = SleighLanguageProvider.getSleighLanguageProvider();
|
||||
SleighLanguage lang = (SleighLanguage) provider.getLanguage(new LanguageID(langId));
|
||||
AtomicReference<Constructor> consref = new AtomicReference<>();
|
||||
SleighLanguages.traverseConstructors(lang, new ConstructorEntryVisitor() {
|
||||
|
|
|
@ -24,9 +24,7 @@ import org.junit.*;
|
|||
|
||||
import db.*;
|
||||
import db.buffers.BufferFile;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.store.db.PrivateDatabase;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.lang.*;
|
||||
|
@ -292,14 +290,8 @@ public class FileBytesTest extends AbstractGenericTest {
|
|||
program.release(this);
|
||||
}
|
||||
|
||||
private Language getLanguage(String languageName) throws Exception {
|
||||
|
||||
ResourceFile ldefFile = Application.getModuleDataFile("Toy", "languages/toy.ldefs");
|
||||
if (ldefFile != null) {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService(ldefFile);
|
||||
Language language = languageService.getLanguage(new LanguageID(languageName));
|
||||
return language;
|
||||
}
|
||||
throw new LanguageNotFoundException("Unsupported test language: " + languageName);
|
||||
private static Language getLanguage(String languageName) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return languageService.getLanguage(new LanguageID(languageName));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,7 @@ import org.junit.*;
|
|||
|
||||
import db.DBConstants;
|
||||
import db.DBHandle;
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.database.map.AddressMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
|
@ -1024,14 +1022,9 @@ public class MemBlockDBTest extends AbstractGenericTest {
|
|||
return addressFactory.getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
|
||||
private Language getLanguage(String languageName) throws Exception {
|
||||
|
||||
ResourceFile ldefFile = Application.getModuleDataFile("Toy", "languages/toy.ldefs");
|
||||
if (ldefFile != null) {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService(ldefFile);
|
||||
Language language = languageService.getLanguage(new LanguageID(languageName));
|
||||
return language;
|
||||
}
|
||||
throw new LanguageNotFoundException("Unsupported test language: " + languageName);
|
||||
private static Language getLanguage(String languageName) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return languageService.getLanguage(new LanguageID(languageName));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,9 +20,7 @@ import static org.junit.Assert.*;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
|
@ -39,14 +37,9 @@ public class VariableUtilitiesTest extends AbstractGenericTest {
|
|||
program = new ProgramDB("Test", language, compilerSpec, this);
|
||||
}
|
||||
|
||||
private Language getLanguage(String languageName) throws Exception {
|
||||
ResourceFile ldefFile = Application.getModuleDataFile("Toy", "languages/toy.ldefs");
|
||||
if (ldefFile != null) {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService(ldefFile);
|
||||
Language language = languageService.getLanguage(new LanguageID(languageName));
|
||||
return language;
|
||||
}
|
||||
throw new LanguageNotFoundException("Unsupported test language: " + languageName);
|
||||
private static Language getLanguage(String languageName) throws LanguageNotFoundException {
|
||||
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||
return languageService.getLanguage(new LanguageID(languageName));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue