mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GT-3350: Consistently ordered classpath and ExtensionPoint priorities
This commit is contained in:
parent
7ab75e411e
commit
8f00152601
52 changed files with 341 additions and 169 deletions
|
@ -17,7 +17,8 @@ package ghidra.app.util.disassemble;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.field.*;
|
import docking.widgets.fieldpanel.field.*;
|
||||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||||
|
@ -43,7 +44,7 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
|
||||||
availableDisassemblers = new ArrayList<>();
|
availableDisassemblers = new ArrayList<>();
|
||||||
|
|
||||||
// find the available external disassemblers
|
// find the available external disassemblers
|
||||||
Set<ExternalDisassembler> extDisassemblers =
|
List<ExternalDisassembler> extDisassemblers =
|
||||||
ClassSearcher.getInstances(ExternalDisassembler.class);
|
ClassSearcher.getInstances(ExternalDisassembler.class);
|
||||||
|
|
||||||
for (ExternalDisassembler disassember : extDisassemblers) {
|
for (ExternalDisassembler disassember : extDisassemblers) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class DumpGhidraCapabilitiesScript extends GhidraScript {
|
||||||
addPlugin(moduleName, pluginDescription);
|
addPlugin(moduleName, pluginDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Analyzer> instances = ClassSearcher.getInstances(Analyzer.class);
|
List<Analyzer> instances = ClassSearcher.getInstances(Analyzer.class);
|
||||||
for (Analyzer analyzer : instances) {
|
for (Analyzer analyzer : instances) {
|
||||||
Class<? extends Analyzer> clazz = analyzer.getClass();
|
Class<? extends Analyzer> clazz = analyzer.getClass();
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class SummarizeAnalyzers extends GhidraScript {
|
||||||
|
|
||||||
Options options = currentProgram.getOptions(Program.ANALYSIS_PROPERTIES);
|
Options options = currentProgram.getOptions(Program.ANALYSIS_PROPERTIES);
|
||||||
|
|
||||||
Set<Class<? extends Analyzer>> classes = ClassSearcher.getClasses(Analyzer.class);
|
List<Class<? extends Analyzer>> classes = ClassSearcher.getClasses(Analyzer.class);
|
||||||
for (Class<? extends Analyzer> element : classes) {
|
for (Class<? extends Analyzer> element : classes) {
|
||||||
Analyzer analyzer;
|
Analyzer analyzer;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.cmd.label;
|
package ghidra.app.cmd.label;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.demangler.*;
|
import ghidra.app.util.demangler.*;
|
||||||
import ghidra.framework.cmd.BackgroundCommand;
|
import ghidra.framework.cmd.BackgroundCommand;
|
||||||
|
@ -33,7 +33,7 @@ public class DemanglerCmd extends BackgroundCommand {
|
||||||
private String mangled;
|
private String mangled;
|
||||||
private String result;
|
private String result;
|
||||||
private DemangledObject demangledObject;
|
private DemangledObject demangledObject;
|
||||||
private static Set<Demangler> demanglers;
|
private static List<Demangler> demanglers;
|
||||||
private DemanglerOptions options;
|
private DemanglerOptions options;
|
||||||
|
|
||||||
public DemanglerCmd(Address addr, String mangled) {
|
public DemanglerCmd(Address addr, String mangled) {
|
||||||
|
@ -138,7 +138,7 @@ public class DemanglerCmd extends BackgroundCommand {
|
||||||
return demangledObject;
|
return demangledObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<Demangler> getDemanglers() {
|
private static List<Demangler> getDemanglers() {
|
||||||
if (demanglers == null) {
|
if (demanglers == null) {
|
||||||
demanglers = ClassSearcher.getInstances(Demangler.class);
|
demanglers = ClassSearcher.getInstances(Demangler.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
|
||||||
taskArray = new AnalysisTaskList[] { byteTasks, instructionTasks, functionTasks,
|
taskArray = new AnalysisTaskList[] { byteTasks, instructionTasks, functionTasks,
|
||||||
functionModifierChangedTasks, functionSignatureChangedTasks, dataTasks };
|
functionModifierChangedTasks, functionSignatureChangedTasks, dataTasks };
|
||||||
|
|
||||||
Set<Analyzer> analyzers = ClassSearcher.getInstances(Analyzer.class);
|
List<Analyzer> analyzers = ClassSearcher.getInstances(Analyzer.class);
|
||||||
for (Analyzer analyzer : analyzers) {
|
for (Analyzer analyzer : analyzers) {
|
||||||
if (!analyzer.canAnalyze(program)) {
|
if (!analyzer.canAnalyze(program)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -19,15 +19,13 @@ import ghidra.program.model.address.AddressSetView;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.program.model.util.MemoryByteIterator;
|
import ghidra.program.model.util.MemoryByteIterator;
|
||||||
import ghidra.util.classfinder.ExtensionPoint;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used for the computation of various basic checksums.
|
* This class is used for the computation of various basic checksums.
|
||||||
*/
|
*/
|
||||||
@ExtensionPoint.Exclude(reason = "Subclasses will get picked up by extension points.")
|
public abstract class BasicChecksumAlgorithm extends ChecksumAlgorithm {
|
||||||
public class BasicChecksumAlgorithm extends ChecksumAlgorithm {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The byte sizes that are supported by the basic checksum algorithm.
|
* The byte sizes that are supported by the basic checksum algorithm.
|
||||||
|
|
|
@ -17,7 +17,8 @@ package ghidra.app.plugin.core.checksums;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ public class ComputeChecksumsProvider extends ComponentProviderAdapter {
|
||||||
super(plugin.getTool(), "Checksum Generator", plugin.getName(), ProgramContextAction.class);
|
super(plugin.getTool(), "Checksum Generator", plugin.getName(), ProgramContextAction.class);
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation("ComputeChecksumsPlugin", "Generate_Checksum_Help"));
|
setHelpLocation(new HelpLocation("ComputeChecksumsPlugin", "Generate_Checksum_Help"));
|
||||||
Set<ChecksumAlgorithm> algorithms = ClassSearcher.getInstances(ChecksumAlgorithm.class);
|
List<ChecksumAlgorithm> algorithms = ClassSearcher.getInstances(ChecksumAlgorithm.class);
|
||||||
checksums.addAll(algorithms);
|
checksums.addAll(algorithms);
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import ghidra.program.model.address.AddressSetView;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.program.model.util.MemoryByteIterator;
|
import ghidra.program.model.util.MemoryByteIterator;
|
||||||
import ghidra.util.classfinder.ExtensionPoint;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -30,8 +29,7 @@ import ghidra.util.task.TaskMonitor;
|
||||||
* This class is used for the computation of various digest checksums that are provided
|
* This class is used for the computation of various digest checksums that are provided
|
||||||
* by java. These checksums do not have options associated with them.
|
* by java. These checksums do not have options associated with them.
|
||||||
*/
|
*/
|
||||||
@ExtensionPoint.Exclude(reason = "Subclasses will get picked up by extension points.")
|
public abstract class DigestChecksumAlgorithm extends ChecksumAlgorithm {
|
||||||
public class DigestChecksumAlgorithm extends ChecksumAlgorithm {
|
|
||||||
|
|
||||||
MessageDigest digester;
|
MessageDigest digester;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class ExportToHeaderAction extends DockingAction {
|
||||||
*/
|
*/
|
||||||
private void exportToC(GTree gTree, DataTypeManager programDataTypeMgr) {
|
private void exportToC(GTree gTree, DataTypeManager programDataTypeMgr) {
|
||||||
|
|
||||||
Set<Class<? extends AnnotationHandler>> classes =
|
List<Class<? extends AnnotationHandler>> classes =
|
||||||
ClassSearcher.getClasses(AnnotationHandler.class);
|
ClassSearcher.getClasses(AnnotationHandler.class);
|
||||||
|
|
||||||
List<AnnotationHandler> list = new ArrayList<>();
|
List<AnnotationHandler> list = new ArrayList<>();
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class FunctionComparisonPanel extends JPanel implements ChangeListener {
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private Set<CodeComparisonPanel<? extends FieldPanelCoordinator>> createAllPossibleCodeComparisonPanels() {
|
private Set<CodeComparisonPanel<? extends FieldPanelCoordinator>> createAllPossibleCodeComparisonPanels() {
|
||||||
Set<CodeComparisonPanel<? extends FieldPanelCoordinator>> instances = new HashSet<>();
|
Set<CodeComparisonPanel<? extends FieldPanelCoordinator>> instances = new HashSet<>();
|
||||||
Set<Class<? extends CodeComparisonPanel>> classes =
|
List<Class<? extends CodeComparisonPanel>> classes =
|
||||||
ClassSearcher.getClasses(CodeComparisonPanel.class);
|
ClassSearcher.getClasses(CodeComparisonPanel.class);
|
||||||
for (Class<? extends CodeComparisonPanel> panelClass : classes) {
|
for (Class<? extends CodeComparisonPanel> panelClass : classes) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -284,7 +284,7 @@ public final class ReferenceUtils {
|
||||||
Accumulator<LocationReference> accumulator, Program program, DataType dataType,
|
Accumulator<LocationReference> accumulator, Program program, DataType dataType,
|
||||||
String fieldName, TaskMonitor monitor) throws CancelledException {
|
String fieldName, TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
Set<DataTypeReferenceFinder> finders =
|
List<DataTypeReferenceFinder> finders =
|
||||||
ClassSearcher.getInstances(DataTypeReferenceFinder.class);
|
ClassSearcher.getInstances(DataTypeReferenceFinder.class);
|
||||||
|
|
||||||
Consumer<DataTypeReference> callback = ref -> {
|
Consumer<DataTypeReference> callback = ref -> {
|
||||||
|
|
|
@ -54,7 +54,7 @@ import resources.ResourceManager;
|
||||||
public class OverviewColorPlugin extends ProgramPlugin {
|
public class OverviewColorPlugin extends ProgramPlugin {
|
||||||
public static final String HELP_TOPIC = "OverviewPlugin";
|
public static final String HELP_TOPIC = "OverviewPlugin";
|
||||||
private static final String ACTIVE_SERVICES = "ActiveServices";
|
private static final String ACTIVE_SERVICES = "ActiveServices";
|
||||||
private Set<OverviewColorService> allServices;
|
private List<OverviewColorService> allServices;
|
||||||
private Map<OverviewColorService, OverviewColorComponent> activeServices =
|
private Map<OverviewColorService, OverviewColorComponent> activeServices =
|
||||||
new LinkedHashMap<>(); // maintain the left to right order of the active overview bars.
|
new LinkedHashMap<>(); // maintain the left to right order of the active overview bars.
|
||||||
private CodeViewerService codeViewerService;
|
private CodeViewerService codeViewerService;
|
||||||
|
|
|
@ -15,18 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.validator;
|
package ghidra.app.plugin.core.validator;
|
||||||
|
|
||||||
import ghidra.app.CorePluginPackage;
|
|
||||||
import ghidra.app.context.ProgramActionContext;
|
|
||||||
import ghidra.app.context.ProgramContextAction;
|
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
|
||||||
import ghidra.app.plugin.core.analysis.validator.PostAnalysisValidator;
|
|
||||||
import ghidra.framework.plugintool.*;
|
|
||||||
import ghidra.framework.plugintool.util.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -35,6 +23,17 @@ import docking.action.DockingAction;
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import docking.tool.ToolConstants;
|
import docking.tool.ToolConstants;
|
||||||
import docking.widgets.conditiontestpanel.ConditionTester;
|
import docking.widgets.conditiontestpanel.ConditionTester;
|
||||||
|
import ghidra.app.CorePluginPackage;
|
||||||
|
import ghidra.app.context.ProgramActionContext;
|
||||||
|
import ghidra.app.context.ProgramContextAction;
|
||||||
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
import ghidra.app.plugin.core.analysis.validator.PostAnalysisValidator;
|
||||||
|
import ghidra.framework.plugintool.*;
|
||||||
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a pop-up dialog to run PostAnalysisValidator tests on the Program
|
* Display a pop-up dialog to run PostAnalysisValidator tests on the Program
|
||||||
|
@ -117,7 +116,7 @@ public class ValidateProgramPlugin extends Plugin {
|
||||||
private List<ConditionTester> getConditionTests(Program program) {
|
private List<ConditionTester> getConditionTests(Program program) {
|
||||||
List<ConditionTester> list = new ArrayList<ConditionTester>();
|
List<ConditionTester> list = new ArrayList<ConditionTester>();
|
||||||
|
|
||||||
Set<Class<? extends PostAnalysisValidator>> validatorClasses =
|
List<Class<? extends PostAnalysisValidator>> validatorClasses =
|
||||||
ClassSearcher.getClasses(PostAnalysisValidator.class);
|
ClassSearcher.getClasses(PostAnalysisValidator.class);
|
||||||
for (Class<? extends PostAnalysisValidator> validatorClass : validatorClasses) {
|
for (Class<? extends PostAnalysisValidator> validatorClass : validatorClasses) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package ghidra.app.util.demangler;
|
package ghidra.app.util.demangler;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ public class DemanglerUtil {
|
||||||
* @return the demangled object or null
|
* @return the demangled object or null
|
||||||
*/
|
*/
|
||||||
public static DemangledObject demangle(String mangled) {
|
public static DemangledObject demangle(String mangled) {
|
||||||
Set<Demangler> demanglers = getDemanglers();
|
List<Demangler> demanglers = getDemanglers();
|
||||||
for (Demangler demangler : demanglers) {
|
for (Demangler demangler : demanglers) {
|
||||||
try {
|
try {
|
||||||
// not sure if we should be doing all symbols, but this is what it used to do
|
// not sure if we should be doing all symbols, but this is what it used to do
|
||||||
|
@ -65,7 +64,7 @@ public class DemanglerUtil {
|
||||||
* @return the demangled object or null
|
* @return the demangled object or null
|
||||||
*/
|
*/
|
||||||
public static DemangledObject demangle(Program program, String mangled) {
|
public static DemangledObject demangle(Program program, String mangled) {
|
||||||
Set<Demangler> demanglers = getDemanglers();
|
List<Demangler> demanglers = getDemanglers();
|
||||||
for (Demangler demangler : demanglers) {
|
for (Demangler demangler : demanglers) {
|
||||||
try {
|
try {
|
||||||
if (!demangler.canDemangle(program)) {
|
if (!demangler.canDemangle(program)) {
|
||||||
|
@ -91,7 +90,7 @@ public class DemanglerUtil {
|
||||||
*
|
*
|
||||||
* @return a list of all demanglers
|
* @return a list of all demanglers
|
||||||
*/
|
*/
|
||||||
private static Set<Demangler> getDemanglers() {
|
private static List<Demangler> getDemanglers() {
|
||||||
return ClassSearcher.getInstances(Demangler.class);
|
return ClassSearcher.getInstances(Demangler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class Annotation {
|
||||||
Map<String, AnnotatedStringHandler> map = new HashMap<>();
|
Map<String, AnnotatedStringHandler> map = new HashMap<>();
|
||||||
|
|
||||||
// find all instances of AnnotatedString
|
// find all instances of AnnotatedString
|
||||||
Set<AnnotatedStringHandler> instances =
|
List<AnnotatedStringHandler> instances =
|
||||||
ClassSearcher.getInstances(AnnotatedStringHandler.class);
|
ClassSearcher.getInstances(AnnotatedStringHandler.class);
|
||||||
|
|
||||||
for (AnnotatedStringHandler instance : instances) {
|
for (AnnotatedStringHandler instance : instances) {
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.format;
|
package ghidra.app.util.viewer.format;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
@ -139,7 +140,7 @@ public class FormatManager implements OptionsChangeListener {
|
||||||
private void getFactorys() {
|
private void getFactorys() {
|
||||||
ClassFilter filter = new ClassExclusionFilter(DummyFieldFactory.class,
|
ClassFilter filter = new ClassExclusionFilter(DummyFieldFactory.class,
|
||||||
SpacerFieldFactory.class, SubDataFieldFactory.class);
|
SpacerFieldFactory.class, SubDataFieldFactory.class);
|
||||||
Set<FieldFactory> instances = ClassSearcher.getInstances(FieldFactory.class, filter);
|
List<FieldFactory> instances = ClassSearcher.getInstances(FieldFactory.class, filter);
|
||||||
List<FieldFactory> list = new ArrayList<>();
|
List<FieldFactory> list = new ArrayList<>();
|
||||||
for (FieldFactory fieldFactory : instances) {
|
for (FieldFactory fieldFactory : instances) {
|
||||||
if (fieldFactory instanceof SpacerFieldFactory) {
|
if (fieldFactory instanceof SpacerFieldFactory) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.util;
|
package ghidra.app.util.viewer.util;
|
||||||
|
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.app.util.viewer.field.*;
|
import ghidra.app.util.viewer.field.*;
|
||||||
|
@ -23,11 +26,6 @@ import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to navigate to an address when user double clicks in a
|
* Helper class to navigate to an address when user double clicks in a
|
||||||
* Field. This class will find {@link FieldMouseHandlerExtension}s by using the {@link ClassSearcher}.
|
* Field. This class will find {@link FieldMouseHandlerExtension}s by using the {@link ClassSearcher}.
|
||||||
|
@ -84,7 +82,7 @@ public class FieldNavigator implements ButtonPressedListener, FieldMouseHandlerS
|
||||||
new HashMap<Class<?>, List<FieldMouseHandler>>();
|
new HashMap<Class<?>, List<FieldMouseHandler>>();
|
||||||
|
|
||||||
// find all instances of AnnotatedString
|
// find all instances of AnnotatedString
|
||||||
Set<FieldMouseHandlerExtension> instances =
|
List<FieldMouseHandlerExtension> instances =
|
||||||
ClassSearcher.getInstances(FieldMouseHandlerExtension.class);
|
ClassSearcher.getInstances(FieldMouseHandlerExtension.class);
|
||||||
for (FieldMouseHandlerExtension fieldMouseHandler : instances) {
|
for (FieldMouseHandlerExtension fieldMouseHandler : instances) {
|
||||||
addHandler(map, fieldMouseHandler);
|
addHandler(map, fieldMouseHandler);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package ghidra.framework;
|
package ghidra.framework;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.GhidraClassLoader;
|
import ghidra.GhidraClassLoader;
|
||||||
|
@ -111,7 +111,7 @@ public class HeadlessGhidraApplicationConfiguration extends ApplicationConfigura
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performModuleInitialization() {
|
private void performModuleInitialization() {
|
||||||
Set<ModuleInitializer> instances = ClassSearcher.getInstances(ModuleInitializer.class);
|
List<ModuleInitializer> instances = ClassSearcher.getInstances(ModuleInitializer.class);
|
||||||
for (ModuleInitializer initializer : instances) {
|
for (ModuleInitializer initializer : instances) {
|
||||||
monitor.setMessage("Initializing " + initializer.getName() + "...");
|
monitor.setMessage("Initializing " + initializer.getName() + "...");
|
||||||
initializer.run();
|
initializer.run();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,12 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework.analysis;
|
package ghidra.framework.analysis;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.services.Analyzer;
|
import ghidra.app.services.Analyzer;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class AnalysisRecipeBuilder {
|
public class AnalysisRecipeBuilder {
|
||||||
|
|
||||||
private static List<Class<? extends Analyzer>> classes;
|
private static List<Class<? extends Analyzer>> classes;
|
||||||
|
@ -39,7 +39,7 @@ public class AnalysisRecipeBuilder {
|
||||||
|
|
||||||
private static AnalysisRecipe buildDefaultRecipe(Program program) {
|
private static AnalysisRecipe buildDefaultRecipe(Program program) {
|
||||||
List<Analyzer> analyzerList = new ArrayList<Analyzer>();
|
List<Analyzer> analyzerList = new ArrayList<Analyzer>();
|
||||||
Set<Analyzer> anayzers = ClassSearcher.getInstances(Analyzer.class);
|
List<Analyzer> anayzers = ClassSearcher.getInstances(Analyzer.class);
|
||||||
for (Analyzer analyzer : anayzers) {
|
for (Analyzer analyzer : anayzers) {
|
||||||
if (analyzer.canAnalyze(program)) {
|
if (analyzer.canAnalyze(program)) {
|
||||||
analyzerList.add(analyzer);
|
analyzerList.add(analyzer);
|
||||||
|
|
|
@ -27,11 +27,11 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.classfinder.ExtensionPoint;
|
import ghidra.util.classfinder.ExtensionPointProperties;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
@ExtensionPoint.Exclude(reason = "requires explicit instantiation to wrap a script")
|
@ExtensionPointProperties(exclude = true) // exclude class from extension point discovery because it has to be directly instantiated in order to wrap the supplied script
|
||||||
public class GhidraScriptAnalyzerAdapter extends AbstractAnalyzer {
|
public class GhidraScriptAnalyzerAdapter extends AbstractAnalyzer {
|
||||||
|
|
||||||
private ResourceFile scriptFile;
|
private ResourceFile scriptFile;
|
||||||
|
|
|
@ -18,7 +18,6 @@ package ghidra.framework.plugintool.dialog;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ public class ManageFrontEndToolTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Class<? extends FrontEndable>> classes = ClassSearcher.getClasses(FrontEndable.class);
|
List<Class<? extends FrontEndable>> classes = ClassSearcher.getClasses(FrontEndable.class);
|
||||||
assertEquals(count, classes.size());
|
assertEquals(count, classes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.app.plugin.core.byteviewer;
|
||||||
|
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -696,7 +697,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
|
||||||
@Override
|
@Override
|
||||||
protected Set<DataFormatModel> getDataFormatModels() {
|
protected Set<DataFormatModel> getDataFormatModels() {
|
||||||
Set<DataFormatModel> dataFormatModels = super.getDataFormatModels();
|
Set<DataFormatModel> dataFormatModels = super.getDataFormatModels();
|
||||||
Set<ProgramDataFormatModel> instances =
|
List<ProgramDataFormatModel> instances =
|
||||||
ClassSearcher.getInstances(ProgramDataFormatModel.class);
|
ClassSearcher.getInstances(ProgramDataFormatModel.class);
|
||||||
dataFormatModels.addAll(instances);
|
dataFormatModels.addAll(instances);
|
||||||
return dataFormatModels;
|
return dataFormatModels;
|
||||||
|
|
|
@ -15,13 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.file.analyzers;
|
package ghidra.file.analyzers;
|
||||||
|
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
import java.util.List;
|
||||||
|
|
||||||
import java.util.Set;
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
public final class FileFormatAnalyzerFactory {
|
public final class FileFormatAnalyzerFactory {
|
||||||
|
|
||||||
public final static Set<FileFormatAnalyzer> getAnalyzers() {
|
public final static List<FileFormatAnalyzer> getAnalyzers() {
|
||||||
return ClassSearcher.getInstances(FileFormatAnalyzer.class);
|
return ClassSearcher.getInstances(FileFormatAnalyzer.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,15 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.file.crypto;
|
package ghidra.file.crypto;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.CryptoException;
|
import ghidra.util.exception.CryptoException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not used by any known code, not tested.
|
* Not used by any known code, not tested.
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +34,7 @@ public final class DecryptorFactory {
|
||||||
ByteProvider provider, TaskMonitor monitor) throws IOException, CryptoException,
|
ByteProvider provider, TaskMonitor monitor) throws IOException, CryptoException,
|
||||||
CancelledException {
|
CancelledException {
|
||||||
|
|
||||||
Set<Decryptor> instances = ClassSearcher.getInstances(Decryptor.class);
|
List<Decryptor> instances = ClassSearcher.getInstances(Decryptor.class);
|
||||||
for (Decryptor decryptor : instances) {
|
for (Decryptor decryptor : instances) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
throw new CancelledException();
|
throw new CancelledException();
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.functiongraph;
|
package ghidra.app.plugin.core.functiongraph;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayout;
|
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayout;
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
|
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
|
||||||
|
@ -27,8 +27,8 @@ import ghidra.util.classfinder.ClassSearcher;
|
||||||
public class DiscoverableFGLayoutFinder implements FGLayoutFinder {
|
public class DiscoverableFGLayoutFinder implements FGLayoutFinder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<FGLayoutProvider> findLayouts() {
|
public List<FGLayoutProvider> findLayouts() {
|
||||||
Set<FGLayoutProvider> instances = ClassSearcher.getInstances(FGLayoutProvider.class);
|
List<FGLayoutProvider> instances = ClassSearcher.getInstances(FGLayoutProvider.class);
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.functiongraph;
|
package ghidra.app.plugin.core.functiongraph;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayout;
|
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayout;
|
||||||
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
|
import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
|
||||||
|
@ -24,5 +24,5 @@ import ghidra.app.plugin.core.functiongraph.graph.layout.FGLayoutProvider;
|
||||||
* An interface that provides {@link FGLayout}s
|
* An interface that provides {@link FGLayout}s
|
||||||
*/
|
*/
|
||||||
public interface FGLayoutFinder {
|
public interface FGLayoutFinder {
|
||||||
public Set<FGLayoutProvider> findLayouts();
|
public List<FGLayoutProvider> findLayouts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class FunctionGraphPlugin extends ProgramPlugin implements OptionsChangeL
|
||||||
private List<FGLayoutProvider> loadLayoutProviders() {
|
private List<FGLayoutProvider> loadLayoutProviders() {
|
||||||
|
|
||||||
FGLayoutFinder layoutFinder = new DiscoverableFGLayoutFinder();
|
FGLayoutFinder layoutFinder = new DiscoverableFGLayoutFinder();
|
||||||
Set<FGLayoutProvider> instances = layoutFinder.findLayouts();
|
List<FGLayoutProvider> instances = layoutFinder.findLayouts();
|
||||||
if (instances.isEmpty()) {
|
if (instances.isEmpty()) {
|
||||||
throw new AssertException("Could not find any layout providers. You project may not " +
|
throw new AssertException("Could not find any layout providers. You project may not " +
|
||||||
"be configured properly.");
|
"be configured properly.");
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class FidService {
|
||||||
this.digestFactory = new FNV1a64MessageDigestFactory();
|
this.digestFactory = new FNV1a64MessageDigestFactory();
|
||||||
this.skippers = new HashMap<>();
|
this.skippers = new HashMap<>();
|
||||||
|
|
||||||
Set<Class<? extends InstructionSkipper>> classes =
|
List<Class<? extends InstructionSkipper>> classes =
|
||||||
ClassSearcher.getClasses(InstructionSkipper.class);
|
ClassSearcher.getClasses(InstructionSkipper.class);
|
||||||
for (Class<? extends InstructionSkipper> clazz : classes) {
|
for (Class<? extends InstructionSkipper> clazz : classes) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.feature.vt;
|
package ghidra.feature.vt;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.feature.vt.api.db.VTSessionDB;
|
import ghidra.feature.vt.api.db.VTSessionDB;
|
||||||
import ghidra.feature.vt.api.main.*;
|
import ghidra.feature.vt.api.main.*;
|
||||||
|
@ -26,9 +29,6 @@ import ghidra.util.classfinder.ClassSearcher;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.VersionException;
|
import ghidra.util.exception.VersionException;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public abstract class GhidraVersionTrackingScript extends GhidraScript {
|
public abstract class GhidraVersionTrackingScript extends GhidraScript {
|
||||||
protected VTSession vtSession;
|
protected VTSession vtSession;
|
||||||
protected Program sourceProgram;
|
protected Program sourceProgram;
|
||||||
|
@ -162,7 +162,7 @@ public abstract class GhidraVersionTrackingScript extends GhidraScript {
|
||||||
|
|
||||||
public List<String> getProgramCorrelators() {
|
public List<String> getProgramCorrelators() {
|
||||||
List<String> correlators = new ArrayList<String>();
|
List<String> correlators = new ArrayList<String>();
|
||||||
Set<VTProgramCorrelatorFactory> generateList = getVTProgramCorrelatorFactory();
|
List<VTProgramCorrelatorFactory> generateList = getVTProgramCorrelatorFactory();
|
||||||
for (VTProgramCorrelatorFactory vtProgramCorrelatorFactory : generateList) {
|
for (VTProgramCorrelatorFactory vtProgramCorrelatorFactory : generateList) {
|
||||||
correlators.add(vtProgramCorrelatorFactory.getName());
|
correlators.add(vtProgramCorrelatorFactory.getName());
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ public abstract class GhidraVersionTrackingScript extends GhidraScript {
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
private VTProgramCorrelatorFactory getCorrelatorFactory(String name) {
|
private VTProgramCorrelatorFactory getCorrelatorFactory(String name) {
|
||||||
Set<VTProgramCorrelatorFactory> generateList = getVTProgramCorrelatorFactory();
|
List<VTProgramCorrelatorFactory> generateList = getVTProgramCorrelatorFactory();
|
||||||
for (VTProgramCorrelatorFactory vtProgramCorrelatorFactory : generateList) {
|
for (VTProgramCorrelatorFactory vtProgramCorrelatorFactory : generateList) {
|
||||||
if (vtProgramCorrelatorFactory.getName().equals(name)) {
|
if (vtProgramCorrelatorFactory.getName().equals(name)) {
|
||||||
return vtProgramCorrelatorFactory;
|
return vtProgramCorrelatorFactory;
|
||||||
|
@ -230,7 +230,7 @@ public abstract class GhidraVersionTrackingScript extends GhidraScript {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<VTProgramCorrelatorFactory> getVTProgramCorrelatorFactory() {
|
private static List<VTProgramCorrelatorFactory> getVTProgramCorrelatorFactory() {
|
||||||
return ClassSearcher.getInstances(VTProgramCorrelatorFactory.class);
|
return ClassSearcher.getInstances(VTProgramCorrelatorFactory.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public abstract class Stringable implements ExtensionPoint, DisplayStringProvide
|
||||||
|
|
||||||
private static void initializeNameMap() {
|
private static void initializeNameMap() {
|
||||||
shortNameToClassnameMap = new HashMap<String, Class<? extends Stringable>>();
|
shortNameToClassnameMap = new HashMap<String, Class<? extends Stringable>>();
|
||||||
Set<Class<? extends Stringable>> classes = ClassSearcher.getClasses(Stringable.class);
|
List<Class<? extends Stringable>> classes = ClassSearcher.getClasses(Stringable.class);
|
||||||
for (Class<? extends Stringable> clazz : classes) {
|
for (Class<? extends Stringable> clazz : classes) {
|
||||||
String name = getShortNameFieldValue(clazz);
|
String name = getShortNameFieldValue(clazz);
|
||||||
shortNameToClassnameMap.put(name, clazz);
|
shortNameToClassnameMap.put(name, clazz);
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class AddressCorrelatorManager {
|
||||||
|
|
||||||
private List<AddressCorrelator> initializeAddressCorrelators() {
|
private List<AddressCorrelator> initializeAddressCorrelators() {
|
||||||
|
|
||||||
Set<DiscoverableAddressCorrelator> instances =
|
List<DiscoverableAddressCorrelator> instances =
|
||||||
ClassSearcher.getInstances(DiscoverableAddressCorrelator.class);
|
ClassSearcher.getInstances(DiscoverableAddressCorrelator.class);
|
||||||
List<AddressCorrelator> addressCorrelatorList = new ArrayList<AddressCorrelator>(instances);
|
List<AddressCorrelator> addressCorrelatorList = new ArrayList<AddressCorrelator>(instances);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ package ghidra.feature.vt.gui.provider.matchtable;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ public class AlgorithmFilter extends CheckBoxBasedAncillaryFilter<VTMatch> {
|
||||||
list.add(ManualMatchProgramCorrelator.NAME);
|
list.add(ManualMatchProgramCorrelator.NAME);
|
||||||
list.add(ImpliedMatchProgramCorrelator.NAME);
|
list.add(ImpliedMatchProgramCorrelator.NAME);
|
||||||
|
|
||||||
Set<VTAbstractProgramCorrelatorFactory> instances =
|
List<VTAbstractProgramCorrelatorFactory> instances =
|
||||||
ClassSearcher.getInstances(VTAbstractProgramCorrelatorFactory.class);
|
ClassSearcher.getInstances(VTAbstractProgramCorrelatorFactory.class);
|
||||||
for (VTAbstractProgramCorrelatorFactory factory : instances) {
|
for (VTAbstractProgramCorrelatorFactory factory : instances) {
|
||||||
list.add(factory.getName());
|
list.add(factory.getName());
|
||||||
|
|
|
@ -15,13 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.feature.vt.gui.wizard;
|
package ghidra.feature.vt.gui.wizard;
|
||||||
|
|
||||||
import ghidra.feature.vt.api.main.VTSession;
|
|
||||||
import ghidra.feature.vt.gui.validator.VTPreconditionValidator;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
@ -33,6 +26,12 @@ import javax.swing.*;
|
||||||
|
|
||||||
import docking.widgets.conditiontestpanel.*;
|
import docking.widgets.conditiontestpanel.*;
|
||||||
import docking.wizard.*;
|
import docking.wizard.*;
|
||||||
|
import ghidra.feature.vt.api.main.VTSession;
|
||||||
|
import ghidra.feature.vt.gui.validator.VTPreconditionValidator;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
public class PreconditionsPanel extends AbstractMageJPanel<VTWizardStateKey> implements Scrollable {
|
public class PreconditionsPanel extends AbstractMageJPanel<VTWizardStateKey> implements Scrollable {
|
||||||
private static final Dimension DEFAULT_SIZE = new Dimension(650, 480);
|
private static final Dimension DEFAULT_SIZE = new Dimension(650, 480);
|
||||||
|
@ -148,7 +147,7 @@ public class PreconditionsPanel extends AbstractMageJPanel<VTWizardStateKey> imp
|
||||||
Program destinationProgram, VTSession existingResults) throws SecurityException {
|
Program destinationProgram, VTSession existingResults) throws SecurityException {
|
||||||
List<ConditionTester> list = new ArrayList<ConditionTester>();
|
List<ConditionTester> list = new ArrayList<ConditionTester>();
|
||||||
|
|
||||||
Set<Class<? extends VTPreconditionValidator>> vtValidatorClasses =
|
List<Class<? extends VTPreconditionValidator>> vtValidatorClasses =
|
||||||
ClassSearcher.getClasses(VTPreconditionValidator.class);
|
ClassSearcher.getClasses(VTPreconditionValidator.class);
|
||||||
for (Class<? extends VTPreconditionValidator> validatorClass : vtValidatorClasses) {
|
for (Class<? extends VTPreconditionValidator> validatorClass : vtValidatorClasses) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -60,13 +60,12 @@ public class VTProgramTableCorrelatorModel extends AbstractGTableModel<VTProgram
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<VTProgramCorrelatorFactory> generateList() {
|
private static List<VTProgramCorrelatorFactory> generateList() {
|
||||||
Set<VTAbstractProgramCorrelatorFactory> instances =
|
List<VTAbstractProgramCorrelatorFactory> instances =
|
||||||
ClassSearcher.getInstances(VTAbstractProgramCorrelatorFactory.class);
|
ClassSearcher.getInstances(VTAbstractProgramCorrelatorFactory.class);
|
||||||
|
|
||||||
List<VTProgramCorrelatorFactory> list =
|
List<VTProgramCorrelatorFactory> list = new ArrayList<>(instances);
|
||||||
new ArrayList<>(instances);
|
|
||||||
|
|
||||||
Collections.sort(list, comparator);
|
Collections.sort(instances, comparator);
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class DiscoverableTableUtils {
|
||||||
Set<TableRowMapper<ROW_TYPE, EXPECTED_TYPE, DATA_SOURCE>> set = new HashSet<>();
|
Set<TableRowMapper<ROW_TYPE, EXPECTED_TYPE, DATA_SOURCE>> set = new HashSet<>();
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
Set<TableRowMapper> instances = ClassSearcher.getInstances(TableRowMapper.class);
|
List<TableRowMapper> instances = ClassSearcher.getInstances(TableRowMapper.class);
|
||||||
for (TableRowMapper<ROW_TYPE, EXPECTED_TYPE, DATA_SOURCE> mapper : instances) {
|
for (TableRowMapper<ROW_TYPE, EXPECTED_TYPE, DATA_SOURCE> mapper : instances) {
|
||||||
if (mapper.getSourceType() == fromType && mapper.getDestinationType() == toType) {
|
if (mapper.getSourceType() == fromType && mapper.getDestinationType() == toType) {
|
||||||
set.add(mapper);
|
set.add(mapper);
|
||||||
|
@ -293,7 +293,7 @@ public class DiscoverableTableUtils {
|
||||||
List<ColumnConstraint<?>> mappedConstraints = new ArrayList<>();
|
List<ColumnConstraint<?>> mappedConstraints = new ArrayList<>();
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
Set<ColumnTypeMapper> mappers = ClassSearcher.getInstances(ColumnTypeMapper.class);
|
List<ColumnTypeMapper> mappers = ClassSearcher.getInstances(ColumnTypeMapper.class);
|
||||||
|
|
||||||
for (ColumnTypeMapper<?, ?> mapper : mappers) {
|
for (ColumnTypeMapper<?, ?> mapper : mappers) {
|
||||||
mappedConstraints.addAll(generateMappedConstraints(mapper, foundConstraints));
|
mappedConstraints.addAll(generateMappedConstraints(mapper, foundConstraints));
|
||||||
|
@ -371,7 +371,7 @@ public class DiscoverableTableUtils {
|
||||||
private static List<ColumnConstraint<?>> findColumnConstraints() {
|
private static List<ColumnConstraint<?>> findColumnConstraints() {
|
||||||
List<ColumnConstraint<?>> constraints = new ArrayList<>();
|
List<ColumnConstraint<?>> constraints = new ArrayList<>();
|
||||||
|
|
||||||
Set<ColumnConstraintProvider> constraintProviders =
|
List<ColumnConstraintProvider> constraintProviders =
|
||||||
ClassSearcher.getInstances(ColumnConstraintProvider.class);
|
ClassSearcher.getInstances(ColumnConstraintProvider.class);
|
||||||
|
|
||||||
for (ColumnConstraintProvider provider : constraintProviders) {
|
for (ColumnConstraintProvider provider : constraintProviders) {
|
||||||
|
|
|
@ -72,21 +72,43 @@ public class ClassFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Class<?>> getClasses(TaskMonitor monitor) throws CancelledException {
|
List<Class<?>> getClasses(TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
Set<Class<?>> classes = new HashSet<>();
|
Set<Class<?>> classSet = new HashSet<>();
|
||||||
|
|
||||||
for (ClassDir dir : classDirs) {
|
for (ClassDir dir : classDirs) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
dir.getClasses(classes, monitor);
|
dir.getClasses(classSet, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClassJar jar : classJars) {
|
for (ClassJar jar : classJars) {
|
||||||
monitor.checkCanceled();
|
monitor.checkCanceled();
|
||||||
jar.getClasses(classes, monitor);
|
jar.getClasses(classSet, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return classes;
|
List<Class<?>> classList = new ArrayList<>(classSet);
|
||||||
|
|
||||||
|
Collections.sort(classList, (c1, c2) -> {
|
||||||
|
// Sort classes primarily by priority and secondarily by name
|
||||||
|
int p1 = ExtensionPointProperties.Util.getPriority(c1);
|
||||||
|
int p2 = ExtensionPointProperties.Util.getPriority(c2);
|
||||||
|
if (p1 > p2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (p1 < p2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
String n1 = c1.getName();
|
||||||
|
String n2 = c2.getName();
|
||||||
|
if (n1.equals(n2)) {
|
||||||
|
// Same priority and same package/class name....just arbitrarily choose one
|
||||||
|
return Integer.compare(c1.hashCode(), c2.hashCode());
|
||||||
|
}
|
||||||
|
return n1.compareTo(n2);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return classList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ static Class<?> loadExtensionPoint(String path, String fullName) {
|
/*package*/ static Class<?> loadExtensionPoint(String path, String fullName) {
|
||||||
|
@ -178,7 +200,7 @@ public class ClassFinder {
|
||||||
if (!Modifier.isPublic(c.getModifiers())) {
|
if (!Modifier.isPublic(c.getModifiers())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ExtensionPoint.Util.isExcluded(c)) {
|
if (ExtensionPointProperties.Util.isExcluded(c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class ClassSearcher {
|
||||||
static final Logger log = LogManager.getLogger(ClassSearcher.class);
|
static final Logger log = LogManager.getLogger(ClassSearcher.class);
|
||||||
|
|
||||||
private static ClassFinder searcher;
|
private static ClassFinder searcher;
|
||||||
private static Set<Class<?>> extensionPoints;
|
private static List<Class<?>> extensionPoints;
|
||||||
|
|
||||||
private static WeakSet<ChangeListener> listenerList =
|
private static WeakSet<ChangeListener> listenerList =
|
||||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||||
|
@ -82,53 +82,67 @@ public class ClassSearcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get classes that implement or derive from the given class
|
* Get {@link ExtensionPointProperties#priority() priority-sorted} classes that implement or
|
||||||
|
* derive from the given class
|
||||||
*
|
*
|
||||||
* @param c class filter class
|
* @param c the filter class
|
||||||
* @return set of classes that implement or extend T
|
* @return set of classes that implement or extend T
|
||||||
*/
|
*/
|
||||||
public static <T> Set<Class<? extends T>> getClasses(Class<T> c) {
|
public static <T> List<Class<? extends T>> getClasses(Class<T> c) {
|
||||||
return getClasses(c, null);
|
return getClasses(c, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get classes that implement or derive from the given class
|
* Get {@link ExtensionPointProperties#priority() priority-sorted} classes that
|
||||||
|
* implement or derive from the given class
|
||||||
*
|
*
|
||||||
* @param c class filter class
|
* @param c the filter class
|
||||||
* @param classFilter A Predicate that tests class objects (that are already of type T)
|
* @param classFilter A Predicate that tests class objects (that are already of type T)
|
||||||
* for further filtering, <code>null</code> is equivalent to "return true"
|
* for further filtering, <code>null</code> is equivalent to "return true"
|
||||||
* @return set of classes that implement or extend T and pass the filtering test performed
|
* @return {@link ExtensionPointProperties#priority() priority-sorted} list of
|
||||||
* by the predicate.
|
* classes that implement or extend T and pass the filtering test performed by the
|
||||||
|
* predicate
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked") // we checked the type of each use so we know the casts are safe
|
@SuppressWarnings("unchecked") // we checked the type of each use so we know the casts are safe
|
||||||
public static <T> Set<Class<? extends T>> getClasses(Class<T> c,
|
public static <T> List<Class<? extends T>> getClasses(Class<T> c,
|
||||||
Predicate<Class<? extends T>> classFilter) {
|
Predicate<Class<? extends T>> classFilter) {
|
||||||
if (isSearching) {
|
if (isSearching) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Cannot call the getClasses() while the ClassSearcher is searching!");
|
"Cannot call the getClasses() while the ClassSearcher is searching!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Class<? extends T>> set = new HashSet<>();
|
List<Class<? extends T>> list = new ArrayList<>();
|
||||||
if (extensionPoints == null) {
|
if (extensionPoints == null) {
|
||||||
return set;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Class<?> extensionPoint : extensionPoints) {
|
for (Class<?> extensionPoint : extensionPoints) {
|
||||||
if (c.isAssignableFrom(extensionPoint) &&
|
if (c.isAssignableFrom(extensionPoint) &&
|
||||||
(classFilter == null || classFilter.test((Class<T>) extensionPoint))) {
|
(classFilter == null || classFilter.test((Class<T>) extensionPoint))) {
|
||||||
set.add((Class<? extends T>) extensionPoint);
|
list.add((Class<? extends T>) extensionPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return set;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Set<T> getInstances(Class<T> c) {
|
public static <T> List<T> getInstances(Class<T> c) {
|
||||||
return getInstances(c, DO_NOTHING_FILTER);
|
return getInstances(c, DO_NOTHING_FILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Set<T> getInstances(Class<T> c, ClassFilter filter) {
|
/**
|
||||||
Set<Class<? extends T>> classes = getClasses(c);
|
* Get {@link ExtensionPointProperties#priority() priority-sorted} classes
|
||||||
Set<T> instances = new HashSet<>();
|
* instances that implement or derive from the given class
|
||||||
|
*
|
||||||
|
* @param c the filter class
|
||||||
|
* @param filter A Predicate that tests class objects (that are already of type T)
|
||||||
|
* for further filtering, <code>null</code> is equivalent to "return true"
|
||||||
|
* @return {@link ExtensionPointProperties#priority() priority-sorted} list of
|
||||||
|
* classes instances that implement or extend T and pass the filtering test performed by
|
||||||
|
* the predicate
|
||||||
|
*/
|
||||||
|
public static <T> List<T> getInstances(Class<T> c, ClassFilter filter) {
|
||||||
|
List<Class<? extends T>> classes = getClasses(c);
|
||||||
|
List<T> instances = new ArrayList<>();
|
||||||
|
|
||||||
for (Class<? extends T> clazz : classes) {
|
for (Class<? extends T> clazz : classes) {
|
||||||
if (!filter.accepts(clazz)) {
|
if (!filter.accepts(clazz)) {
|
||||||
|
@ -298,7 +312,7 @@ public class ClassSearcher {
|
||||||
ResourceFile extensionClassesFile = new ResourceFile(appRoot, "EXTENSION_POINT_CLASSES");
|
ResourceFile extensionClassesFile = new ResourceFile(appRoot, "EXTENSION_POINT_CLASSES");
|
||||||
try {
|
try {
|
||||||
List<String> classNames = FileUtilities.getLines(extensionClassesFile);
|
List<String> classNames = FileUtilities.getLines(extensionClassesFile);
|
||||||
Set<Class<?>> extensionClasses = new HashSet<>();
|
List<Class<?>> extensionClasses = new ArrayList<>();
|
||||||
for (String className : classNames) {
|
for (String className : classNames) {
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = Class.forName(className);
|
Class<?> clazz = Class.forName(className);
|
||||||
|
@ -308,7 +322,7 @@ public class ClassSearcher {
|
||||||
Msg.warn(ClassSearcher.class, "Can't load extension point: " + className);
|
Msg.warn(ClassSearcher.class, "Can't load extension point: " + className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extensionPoints = Collections.unmodifiableSet(extensionClasses);
|
extensionPoints = Collections.unmodifiableList(extensionClasses);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,11 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.util.classfinder;
|
package ghidra.util.classfinder;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: ExtensionPoint logistics have changed! It is no longer sufficient to
|
* NOTE: ExtensionPoint logistics have changed! It is no longer sufficient to
|
||||||
* implement ExtensionPoint in order for the ClassSearcher to dynamically pick
|
* implement ExtensionPoint in order for the ClassSearcher to dynamically pick
|
||||||
|
@ -35,15 +29,5 @@ import java.lang.annotation.Target;
|
||||||
* will automatically search for and load.
|
* will automatically search for and load.
|
||||||
*/
|
*/
|
||||||
public interface ExtensionPoint {
|
public interface ExtensionPoint {
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
// Marker interface
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public static @interface Exclude {
|
|
||||||
String reason();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Util {
|
|
||||||
public static boolean isExcluded(Class<?> c) {
|
|
||||||
return c.getAnnotation(Exclude.class) != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.util.classfinder;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ExtensionPoint} properties
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface ExtensionPointProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default {@link ExtensionPoint} priority. Higher values represent higher priorities.
|
||||||
|
*/
|
||||||
|
final static int DEFAULT_PRIORITY = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default behavior for an {@link ExtensionPoint} being discoverable
|
||||||
|
*/
|
||||||
|
final static boolean DEFAULT_EXCLUDE = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ExtensionPoint} priority. Higher values represent higher priorities.
|
||||||
|
*
|
||||||
|
* @return the {@link ExtensionPoint} priority.
|
||||||
|
*/
|
||||||
|
int priority() default DEFAULT_PRIORITY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable to exclude an {@link ExtensionPoint} from being discovered
|
||||||
|
*
|
||||||
|
* @return true to exclude an {@link ExtensionPoint} from being discovered
|
||||||
|
*/
|
||||||
|
boolean exclude() default DEFAULT_EXCLUDE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for working with {@link ExtensionPointProperties}
|
||||||
|
*/
|
||||||
|
public static class Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether or not the {@link ExtensionPoint} will be excluded from being discovered
|
||||||
|
*
|
||||||
|
* @param c the class check
|
||||||
|
* @return true if the class is an {@link ExtensionPoint} and should be excluded from being
|
||||||
|
* discovered
|
||||||
|
*/
|
||||||
|
public static boolean isExcluded(Class<?> c) {
|
||||||
|
ExtensionPointProperties properties = c.getAnnotation(ExtensionPointProperties.class);
|
||||||
|
return properties != null ? properties.exclude()
|
||||||
|
: ExtensionPointProperties.DEFAULT_EXCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link ExtensionPoint} priority.
|
||||||
|
*
|
||||||
|
* @param c the class to get {@link ExtensionPoint} priority of.
|
||||||
|
* @return the class's {@link ExtensionPoint} priority
|
||||||
|
* ({@link ExtensionPointProperties#DEFAULT_PRIORITY} will be used in a
|
||||||
|
* non-{@link ExtensionPoint} is passed in)
|
||||||
|
*/
|
||||||
|
public static int getPriority(Class<?> c) {
|
||||||
|
ExtensionPointProperties properties = c.getAnnotation(ExtensionPointProperties.class);
|
||||||
|
return properties != null ? properties.priority()
|
||||||
|
: ExtensionPointProperties.DEFAULT_PRIORITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,12 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework.data;
|
package ghidra.framework.data;
|
||||||
|
|
||||||
import ghidra.framework.model.*;
|
|
||||||
import ghidra.framework.store.FileSystem;
|
|
||||||
import ghidra.framework.store.LockException;
|
|
||||||
import ghidra.util.Lock;
|
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -29,6 +22,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
import ghidra.framework.model.*;
|
||||||
|
import ghidra.framework.store.FileSystem;
|
||||||
|
import ghidra.framework.store.LockException;
|
||||||
|
import ghidra.util.Lock;
|
||||||
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that provides default behavior for
|
* An abstract class that provides default behavior for
|
||||||
* DomainObject(s), specifically it handles listeners and
|
* DomainObject(s), specifically it handles listeners and
|
||||||
|
@ -488,7 +487,7 @@ public abstract class DomainObjectAdapter implements DomainObject {
|
||||||
contentHandlerClassMap = new HashMap<Class<?>, ContentHandler>();
|
contentHandlerClassMap = new HashMap<Class<?>, ContentHandler>();
|
||||||
contentHandlerTypeMap = new HashMap<String, ContentHandler>();
|
contentHandlerTypeMap = new HashMap<String, ContentHandler>();
|
||||||
|
|
||||||
Set<ContentHandler> handlers = ClassSearcher.getInstances(ContentHandler.class);
|
List<ContentHandler> handlers = ClassSearcher.getInstances(ContentHandler.class);
|
||||||
for (ContentHandler ch : handlers) {
|
for (ContentHandler ch : handlers) {
|
||||||
String type = ch.getContentType();
|
String type = ch.getContentType();
|
||||||
Class<?> DOClass = ch.getDomainObjectClass();
|
Class<?> DOClass = ch.getDomainObjectClass();
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class ProjectDataTableModel extends ThreadedTableModel<DomainFileInfo, Pr
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private List<ProjectDataColumn<?>> findAppSpecificColumns() {
|
private List<ProjectDataColumn<?>> findAppSpecificColumns() {
|
||||||
Set<ProjectDataColumn> instances = ClassSearcher.getInstances(ProjectDataColumn.class);
|
List<ProjectDataColumn> instances = ClassSearcher.getInstances(ProjectDataColumn.class);
|
||||||
List<ProjectDataColumn<?>> columns = new ArrayList<>();
|
List<ProjectDataColumn<?>> columns = new ArrayList<>();
|
||||||
|
|
||||||
for (ProjectDataColumn projectDataColumn : instances) {
|
for (ProjectDataColumn projectDataColumn : instances) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class PluginClassManager {
|
||||||
(localExclusionClass == null || !localExclusionClass.isAssignableFrom(c)) &&
|
(localExclusionClass == null || !localExclusionClass.isAssignableFrom(c)) &&
|
||||||
!ProgramaticUseOnly.class.isAssignableFrom(c);
|
!ProgramaticUseOnly.class.isAssignableFrom(c);
|
||||||
|
|
||||||
Set<Class<? extends Plugin>> classes =
|
List<Class<? extends Plugin>> classes =
|
||||||
ClassSearcher.getClasses(Plugin.class, myClassFilter);
|
ClassSearcher.getClasses(Plugin.class, myClassFilter);
|
||||||
|
|
||||||
for (Class<? extends Plugin> pluginClass : classes) {
|
for (Class<? extends Plugin> pluginClass : classes) {
|
||||||
|
|
|
@ -49,7 +49,8 @@ public abstract class PluginPackage implements ExtensionPoint, Comparable<Plugin
|
||||||
|
|
||||||
private static Map<String, PluginPackage> createPackageMap() {
|
private static Map<String, PluginPackage> createPackageMap() {
|
||||||
Map<String, PluginPackage> map = new HashMap<>();
|
Map<String, PluginPackage> map = new HashMap<>();
|
||||||
Set<Class<? extends PluginPackage>> classes = ClassSearcher.getClasses(PluginPackage.class);
|
List<Class<? extends PluginPackage>> classes =
|
||||||
|
ClassSearcher.getClasses(PluginPackage.class);
|
||||||
for (Class<? extends PluginPackage> class1 : classes) {
|
for (Class<? extends PluginPackage> class1 : classes) {
|
||||||
PluginPackage pluginPackage;
|
PluginPackage pluginPackage;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class PluginUtils {
|
||||||
|
|
||||||
// Now get all Plugin.class files that have been loaded, and see if any of them
|
// Now get all Plugin.class files that have been loaded, and see if any of them
|
||||||
// were loaded from one of the jars we just found.
|
// were loaded from one of the jars we just found.
|
||||||
Set<Class<? extends Plugin>> plugins = ClassSearcher.getClasses(Plugin.class);
|
List<Class<? extends Plugin>> plugins = ClassSearcher.getClasses(Plugin.class);
|
||||||
for (Class<? extends Plugin> plugin : plugins) {
|
for (Class<? extends Plugin> plugin : plugins) {
|
||||||
URL location = plugin.getResource('/' + plugin.getName().replace('.', '/') + ".class");
|
URL location = plugin.getResource('/' + plugin.getName().replace('.', '/') + ".class");
|
||||||
if (location == null) {
|
if (location == null) {
|
||||||
|
|
|
@ -390,7 +390,7 @@ class ToolServicesImpl implements ToolServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
contentHandlers = new HashSet<>();
|
contentHandlers = new HashSet<>();
|
||||||
Set<ContentHandler> instances = ClassSearcher.getInstances(ContentHandler.class);
|
List<ContentHandler> instances = ClassSearcher.getInstances(ContentHandler.class);
|
||||||
for (ContentHandler contentHandler : instances) {
|
for (ContentHandler contentHandler : instances) {
|
||||||
// a bit of validation
|
// a bit of validation
|
||||||
String contentType = contentHandler.getContentType();
|
String contentType = contentHandler.getContentType();
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class Handler extends URLStreamHandler {
|
||||||
|
|
||||||
private static void loadGhidraProtocolHandlers() {
|
private static void loadGhidraProtocolHandlers() {
|
||||||
protocolHandlers = new ArrayList<>();
|
protocolHandlers = new ArrayList<>();
|
||||||
Set<Class<? extends GhidraProtocolHandler>> classes =
|
List<Class<? extends GhidraProtocolHandler>> classes =
|
||||||
ClassSearcher.getClasses(GhidraProtocolHandler.class);
|
ClassSearcher.getClasses(GhidraProtocolHandler.class);
|
||||||
for (Class<?> c : classes) {
|
for (Class<?> c : classes) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package ghidra.program.model.data;
|
package ghidra.program.model.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ public class BuiltInDataTypeManager extends StandAloneDataTypeManager {
|
||||||
try {
|
try {
|
||||||
ArrayList<DataType> list = new ArrayList<>();
|
ArrayList<DataType> list = new ArrayList<>();
|
||||||
ClassFilter filter = new BuiltInDataTypeClassExclusionFilter();
|
ClassFilter filter = new BuiltInDataTypeClassExclusionFilter();
|
||||||
Set<BuiltInDataType> datatypes =
|
List<BuiltInDataType> datatypes =
|
||||||
ClassSearcher.getInstances(BuiltInDataType.class, filter);
|
ClassSearcher.getInstances(BuiltInDataType.class, filter);
|
||||||
for (BuiltInDataType datatype : datatypes) {
|
for (BuiltInDataType datatype : datatypes) {
|
||||||
list.clear();
|
list.clear();
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class SymbolUtilities {
|
||||||
private static List<String> getDynamicDataTypePrefixes() {
|
private static List<String> getDynamicDataTypePrefixes() {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
ClassFilter filter = new BuiltInDataTypeClassExclusionFilter();
|
ClassFilter filter = new BuiltInDataTypeClassExclusionFilter();
|
||||||
Set<BuiltInDataType> instances = ClassSearcher.getInstances(BuiltInDataType.class, filter);
|
List<BuiltInDataType> instances = ClassSearcher.getInstances(BuiltInDataType.class, filter);
|
||||||
for (BuiltInDataType builtIn : instances) {
|
for (BuiltInDataType builtIn : instances) {
|
||||||
String prefix = builtIn.getDefaultAbbreviatedLabelPrefix();
|
String prefix = builtIn.getDefaultAbbreviatedLabelPrefix();
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchForProviders() {
|
private void searchForProviders() {
|
||||||
Set<LanguageProvider> languageProviders =
|
List<LanguageProvider> languageProviders =
|
||||||
ClassSearcher.getInstances(LanguageProvider.class);
|
ClassSearcher.getInstances(LanguageProvider.class);
|
||||||
|
|
||||||
searchCompleted = true;
|
searchCompleted = true;
|
||||||
|
@ -338,7 +338,7 @@ public class DefaultLanguageService implements LanguageService, ChangeListener {
|
||||||
throw new LanguageNotFoundException(processor);
|
throw new LanguageNotFoundException(processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processProviders(Set<LanguageProvider> providers) {
|
private void processProviders(List<LanguageProvider> providers) {
|
||||||
for (LanguageProvider provider : providers) {
|
for (LanguageProvider provider : providers) {
|
||||||
addLanguages(provider);
|
addLanguages(provider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,18 +15,18 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.util.constraint;
|
package ghidra.util.constraint;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import generic.constraint.DecisionTree;
|
import generic.constraint.DecisionTree;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.classfinder.ClassSearcher;
|
import ghidra.util.classfinder.ClassSearcher;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class ProgramDecisionTree extends DecisionTree<Program> {
|
public class ProgramDecisionTree extends DecisionTree<Program> {
|
||||||
public ProgramDecisionTree() {
|
public ProgramDecisionTree() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
Set<Class<? extends ProgramConstraint>> classes =
|
List<Class<? extends ProgramConstraint>> classes =
|
||||||
ClassSearcher.getClasses(ProgramConstraint.class);
|
ClassSearcher.getClasses(ProgramConstraint.class);
|
||||||
for (Class<? extends ProgramConstraint> constraintClass : classes) {
|
for (Class<? extends ProgramConstraint> constraintClass : classes) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.stream.Collectors;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.framework.GModule;
|
import ghidra.framework.GModule;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
|
import utility.application.ApplicationLayout;
|
||||||
import utility.module.ModuleUtilities;
|
import utility.module.ModuleUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,15 +53,17 @@ public class GhidraLauncher {
|
||||||
|
|
||||||
// Build the classpath
|
// Build the classpath
|
||||||
List<String> classpathList = new ArrayList<String>();
|
List<String> classpathList = new ArrayList<String>();
|
||||||
|
Map<String, GModule> modules = getOrderedModules(layout);
|
||||||
|
|
||||||
if (SystemUtilities.isInDevelopmentMode()) {
|
if (SystemUtilities.isInDevelopmentMode()) {
|
||||||
addModuleBinPaths(classpathList, layout.getModules());
|
addModuleBinPaths(classpathList, modules);
|
||||||
addExternalJarPaths(classpathList, layout.getApplicationRootDirs());
|
addExternalJarPaths(classpathList, layout.getApplicationRootDirs());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addPatchPaths(classpathList, layout.getApplicationInstallationDir());
|
addPatchPaths(classpathList, layout.getApplicationInstallationDir());
|
||||||
addModuleJarPaths(classpathList, layout.getModules());
|
addModuleJarPaths(classpathList, modules);
|
||||||
}
|
}
|
||||||
classpathList = orderClasspath(classpathList, layout.getModules());
|
classpathList = orderClasspath(classpathList, modules);
|
||||||
|
|
||||||
// Add the classpath to the class loader
|
// Add the classpath to the class loader
|
||||||
GhidraClassLoader loader = (GhidraClassLoader) ClassLoader.getSystemClassLoader();
|
GhidraClassLoader loader = (GhidraClassLoader) ClassLoader.getSystemClassLoader();
|
||||||
|
@ -189,6 +192,63 @@ public class GhidraLauncher {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the modules ordered by "class-loader priority". This ensures that core modules (things
|
||||||
|
* in Framework/Features/Processors, etc) come before user modules (Extensions). It also
|
||||||
|
* guarantees a consistent module order from run to run.
|
||||||
|
*
|
||||||
|
* @param layout The layout
|
||||||
|
* @return the modules mapped by name, ordered by priority
|
||||||
|
*/
|
||||||
|
private static Map<String, GModule> getOrderedModules(ApplicationLayout layout) {
|
||||||
|
|
||||||
|
Comparator<GModule> comparator = (module1, module2) -> {
|
||||||
|
int nameComparison = module1.getName().compareTo(module2.getName());
|
||||||
|
|
||||||
|
// First handle modules that are external to the Ghidra installation.
|
||||||
|
// These should be put at the end of the list.
|
||||||
|
boolean external1 = ModuleUtilities.isExternalModule(module1, layout);
|
||||||
|
boolean external2 = ModuleUtilities.isExternalModule(module2, layout);
|
||||||
|
if (external1 && external2) {
|
||||||
|
return nameComparison;
|
||||||
|
}
|
||||||
|
if (external1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (external2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now handle modules that are internal to the Ghidra installation.
|
||||||
|
// We will primarily order them by "type" and secondarily by name.
|
||||||
|
Map<String, Integer> typePriorityMap = Map.of(
|
||||||
|
"Framework", 0,
|
||||||
|
"Configurations", 1,
|
||||||
|
"Features", 2,
|
||||||
|
"Processors", 3,
|
||||||
|
"GPL", 4,
|
||||||
|
"Extensions", 5,
|
||||||
|
"Test", 6
|
||||||
|
);
|
||||||
|
String type1 = module1.getModuleRoot().getParentFile().getName();
|
||||||
|
String type2 = module2.getModuleRoot().getParentFile().getName();
|
||||||
|
int priority1 = typePriorityMap.getOrDefault(type1, typePriorityMap.size());
|
||||||
|
int priority2 = typePriorityMap.getOrDefault(type2, typePriorityMap.size());
|
||||||
|
if (priority1 != priority2) {
|
||||||
|
return Integer.compare(priority1, priority2);
|
||||||
|
}
|
||||||
|
return nameComparison;
|
||||||
|
};
|
||||||
|
|
||||||
|
List<GModule> moduleList = new ArrayList<>(layout.getModules().values());
|
||||||
|
Collections.sort(moduleList, comparator);
|
||||||
|
Map<String, GModule> moduleMap = new LinkedHashMap<>();
|
||||||
|
for (GModule module : moduleList) {
|
||||||
|
moduleMap.put(module.getName(), module);
|
||||||
|
}
|
||||||
|
return moduleMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the list of paths to make sure the order is correct for any class-loading dependencies.
|
* Updates the list of paths to make sure the order is correct for any class-loading dependencies.
|
||||||
*
|
*
|
||||||
|
@ -199,18 +259,16 @@ public class GhidraLauncher {
|
||||||
private static List<String> orderClasspath(List<String> pathList,
|
private static List<String> orderClasspath(List<String> pathList,
|
||||||
Map<String, GModule> modules) {
|
Map<String, GModule> modules) {
|
||||||
|
|
||||||
//@formatter:off
|
Set<String> fatJars = modules
|
||||||
Set<String> flatJars = modules
|
|
||||||
.values()
|
.values()
|
||||||
.stream()
|
.stream()
|
||||||
.flatMap(m -> m.getFatJars().stream())
|
.flatMap(m -> m.getFatJars().stream())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
List<String> orderedList = new ArrayList<String>(pathList);
|
List<String> orderedList = new ArrayList<String>(pathList);
|
||||||
|
|
||||||
for (String path : pathList) {
|
for (String path : pathList) {
|
||||||
if (flatJars.contains(new File(path).getName())) {
|
if (fatJars.contains(new File(path).getName())) {
|
||||||
orderedList.remove(path);
|
orderedList.remove(path);
|
||||||
orderedList.add(path);
|
orderedList.add(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import ghidra.util.Msg;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
import utility.application.ApplicationLayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for module related things.
|
* Utility methods for module related things.
|
||||||
|
@ -334,4 +335,21 @@ public class ModuleUtilities {
|
||||||
}
|
}
|
||||||
return findRepo(f.getParentFile());
|
return findRepo(f.getParentFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if the given {@link GModule module} is external to the Ghidra installation
|
||||||
|
* directory
|
||||||
|
*
|
||||||
|
* @param module the module to check
|
||||||
|
* @param layout Ghidra's layout
|
||||||
|
* @return true if the given {@link GModule module} is external to the Ghidra installation
|
||||||
|
* directory
|
||||||
|
*/
|
||||||
|
public static boolean isExternalModule(GModule module, ApplicationLayout layout) {
|
||||||
|
File moduleRootDir = module.getModuleRoot().getFile(false);
|
||||||
|
return !layout.getApplicationRootDirs()
|
||||||
|
.stream()
|
||||||
|
.map(dir -> dir.getParentFile().getFile(false))
|
||||||
|
.anyMatch(dir -> FileUtilities.isPathContainedWithin(dir, moduleRootDir));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue