mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-3490: Fixing GhidraDev classpath issues
This commit is contained in:
parent
8cde73e787
commit
88bec10e60
16 changed files with 285 additions and 141 deletions
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -100,6 +100,15 @@ public class GhidraLaunchDelegate extends JavaLaunchDelegate {
|
|||
// Set VM arguments
|
||||
String vmArgs = javaConfig.getLaunchProperties().getVmArgs();
|
||||
vmArgs += " " + configuration.getAttribute(GhidraLaunchUtils.ATTR_VM_ARGUMENTS, "").trim();
|
||||
vmArgs += " -Dghidra.external.modules=\"%s%s%s\"".formatted(
|
||||
javaProject.getProject().getLocation(), File.pathSeparator,
|
||||
getProjectDependencyDirs(javaProject));
|
||||
File pyDevSrcDir = PyDevUtils.getPyDevSrcDir();
|
||||
if (pyDevSrcDir != null) {
|
||||
vmArgs += " " + "-Declipse.pysrc.dir=\"" + pyDevSrcDir + "\"";
|
||||
}
|
||||
|
||||
//---------Legacy properties--------------
|
||||
vmArgs += " " + "-Declipse.install.dir=\"" +
|
||||
Platform.getInstallLocation().getURL().getFile() + "\"";
|
||||
vmArgs += " " + "-Declipse.workspace.dir=\"" +
|
||||
|
@ -107,10 +116,8 @@ public class GhidraLaunchDelegate extends JavaLaunchDelegate {
|
|||
vmArgs += " " + "-Declipse.project.dir=\"" + javaProject.getProject().getLocation() + "\"";
|
||||
vmArgs += " " + "-Declipse.project.dependencies=\"" +
|
||||
getProjectDependencyDirs(javaProject) + "\"";
|
||||
File pyDevSrcDir = PyDevUtils.getPyDevSrcDir();
|
||||
if (pyDevSrcDir != null) {
|
||||
vmArgs += " " + "-Declipse.pysrc.dir=\"" + pyDevSrcDir + "\"";
|
||||
}
|
||||
//----------------------------------------
|
||||
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs);
|
||||
|
||||
// Handle special debug mode tasks
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -22,7 +22,8 @@ import org.eclipse.core.runtime.CoreException;
|
|||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.ui.*;
|
||||
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
|
||||
import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
|
||||
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaDependenciesTab;
|
||||
import org.eclipse.jdt.debug.ui.launchConfigurations.JavaMainTab;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
|
@ -47,7 +48,8 @@ public class GhidraLaunchTabGroup extends AbstractLaunchConfigurationTabGroup {
|
|||
List<ILaunchConfigurationTab> tabs = new ArrayList<>();
|
||||
tabs.add(getJavaMainTab());
|
||||
tabs.add(getUserDefinedArgumentsTab());
|
||||
tabs.add(new JavaClasspathTab());
|
||||
tabs.add(getJavaDependenciesTab());
|
||||
tabs.add(getSourceLookupTab());
|
||||
tabs.add(new EnvironmentTab());
|
||||
tabs.add(getCommonTab());
|
||||
|
||||
|
@ -169,6 +171,49 @@ public class GhidraLaunchTabGroup extends AbstractLaunchConfigurationTabGroup {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link JavaDependenciesTab} to use, with all Ghidra jars removed except Utility.jar.
|
||||
*
|
||||
* @return The {@link JavaDependenciesTab} to use, with all Ghidra jars removed except
|
||||
* Utility.jar.
|
||||
*/
|
||||
private JavaDependenciesTab getJavaDependenciesTab() {
|
||||
return new JavaDependenciesTab() {
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
GhidraLaunchUtils.setClasspath(wc);
|
||||
super.initializeFrom(wc.doSave());
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the java dependencies tab.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link SourceLookupTab} to use, with all Ghidra jars added.
|
||||
*
|
||||
* @return The {@link SourceLookupTab} to use, with all Ghidra jars added.
|
||||
*/
|
||||
private SourceLookupTab getSourceLookupTab() {
|
||||
return new SourceLookupTab() {
|
||||
@Override
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
try {
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
GhidraLaunchUtils.setSource(wc);
|
||||
super.initializeFrom(wc.doSave());
|
||||
}
|
||||
catch (CoreException e) {
|
||||
EclipseMessageUtils.error("Failed to initialize the source lookup tab.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link CommonTab} to use, with the new launch configuration added to the favorites.
|
||||
*
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -19,13 +19,15 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.debug.core.*;
|
||||
import org.eclipse.debug.internal.ui.DebugUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
|
||||
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchHistory;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.jdt.core.IClasspathEntry;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
|
||||
import org.eclipse.jdt.launching.*;
|
||||
|
||||
import ghidra.GhidraLauncher;
|
||||
|
||||
|
@ -83,6 +85,8 @@ public class GhidraLaunchUtils {
|
|||
javaProject.getProject().getName());
|
||||
setMainTypeName(wc);
|
||||
setMemory(wc, runConfigMemory);
|
||||
setClasspath(wc);
|
||||
setSource(wc);
|
||||
setFavorites(wc);
|
||||
return wc;
|
||||
}
|
||||
|
@ -168,6 +172,63 @@ public class GhidraLaunchUtils {
|
|||
return wc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all project jars from the classpath except Utility.jar.
|
||||
*
|
||||
* @param wc The launch configuration working copy to modify.
|
||||
* @return The modified working copy.
|
||||
* @throws CoreException if there was an Eclipse-related issue modifying the classpath.
|
||||
*/
|
||||
public static ILaunchConfigurationWorkingCopy setClasspath(ILaunchConfigurationWorkingCopy wc)
|
||||
throws CoreException {
|
||||
List<String> newList = new ArrayList<>();
|
||||
for (IRuntimeClasspathEntry entry : JavaRuntime.computeUnresolvedRuntimeClasspath(wc)) {
|
||||
switch (entry.getClasspathEntry().getEntryKind()) {
|
||||
case IClasspathEntry.CPE_LIBRARY:
|
||||
if (entry.getPath().toOSString().endsWith("Utility.jar")) {
|
||||
newList.add(entry.getMemento());
|
||||
}
|
||||
break;
|
||||
case IClasspathEntry.CPE_CONTAINER:
|
||||
newList.add(entry.getMemento());
|
||||
break;
|
||||
case IClasspathEntry.CPE_PROJECT:
|
||||
case IClasspathEntry.CPE_SOURCE:
|
||||
case IClasspathEntry.CPE_VARIABLE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, newList);
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
|
||||
return wc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all project jars that have associated source to the source path
|
||||
*
|
||||
* @param wc The launch configuration working copy to modify.
|
||||
* @return The modified working copy.
|
||||
* @throws CoreException if there was an Eclipse-related issue modifying the source path.
|
||||
*/
|
||||
public static ILaunchConfigurationWorkingCopy setSource(ILaunchConfigurationWorkingCopy wc)
|
||||
throws CoreException {
|
||||
List<String> newList = new ArrayList<>();
|
||||
IJavaProject javaProject = JavaRuntime.getJavaProject(wc);
|
||||
if (javaProject != null) {
|
||||
for (IClasspathEntry entry : javaProject.getRawClasspath()) {
|
||||
IPath sourcePath = entry.getSourceAttachmentPath();
|
||||
if (sourcePath != null) {
|
||||
newList.add(
|
||||
JavaRuntime.newArchiveRuntimeClasspathEntry(sourcePath).getMemento());
|
||||
}
|
||||
}
|
||||
}
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH, newList);
|
||||
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_SOURCE_PATH, false);
|
||||
return wc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the favorites attribute in the provided working copy to include the launcher in both
|
||||
* the run and debug launch groups.
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -62,6 +62,14 @@ public class GhidraModuleUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a source folder and its corresponding output folder
|
||||
*
|
||||
* @param sourceFolder The source folder
|
||||
* @param outputFolder The output folder
|
||||
*/
|
||||
private record SourceFolderInfo(IFolder sourceFolder, IFolder outputFolder) {}
|
||||
|
||||
/**
|
||||
* Creates a new Ghidra module project with the given name.
|
||||
*
|
||||
|
@ -90,20 +98,27 @@ public class GhidraModuleUtils {
|
|||
IProject project = javaProject.getProject();
|
||||
|
||||
// Create source directories
|
||||
List<IFolder> sourceFolders = new ArrayList<>();
|
||||
sourceFolders.add(project.getFolder("src/main/java"));
|
||||
sourceFolders.add(project.getFolder("src/main/help"));
|
||||
sourceFolders.add(project.getFolder("src/main/resources"));
|
||||
sourceFolders.add(project.getFolder("src/test/java"));
|
||||
sourceFolders.add(project.getFolder("ghidra_scripts"));
|
||||
for (IFolder sourceFolder : sourceFolders) {
|
||||
GhidraProjectUtils.createFolder(sourceFolder, monitor);
|
||||
List<SourceFolderInfo> sourceFolderInfos = new ArrayList<>();
|
||||
sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/java"),
|
||||
project.getFolder("bin/main")));
|
||||
sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/help"),
|
||||
project.getFolder("bin/main")));
|
||||
sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/resources"),
|
||||
project.getFolder("bin/main")));
|
||||
sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/test/java"),
|
||||
project.getFolder("bin/test")));
|
||||
sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("ghidra_scripts"),
|
||||
project.getFolder("bin/scripts")));
|
||||
for (SourceFolderInfo sourceFolderInfo : sourceFolderInfos) {
|
||||
GhidraProjectUtils.createFolder(sourceFolderInfo.outputFolder(), monitor);
|
||||
}
|
||||
|
||||
// Put the source directories in the project's classpath
|
||||
List<IClasspathEntry> classpathEntries = new LinkedList<>();
|
||||
for (IFolder sourceFolder : sourceFolders) {
|
||||
classpathEntries.add(JavaCore.newSourceEntry(sourceFolder.getFullPath()));
|
||||
for (SourceFolderInfo sourceFolderInfo : sourceFolderInfos) {
|
||||
classpathEntries
|
||||
.add(JavaCore.newSourceEntry(sourceFolderInfo.sourceFolder().getFullPath(),
|
||||
new IPath[0], sourceFolderInfo.outputFolder().getFullPath()));
|
||||
}
|
||||
GhidraProjectUtils.addToClasspath(javaProject, classpathEntries, monitor);
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -301,8 +301,8 @@ public class GhidraProjectUtils {
|
|||
// Configure Java compiler for the project
|
||||
configureJavaCompiler(javaProject, javaConfig);
|
||||
|
||||
// Setup bin folder
|
||||
IFolder binFolder = project.getFolder("bin");
|
||||
// Setup default bin folder
|
||||
IFolder binFolder = project.getFolder("bin/default");
|
||||
javaProject.setOutputLocation(binFolder.getFullPath(), monitor);
|
||||
|
||||
// Add Eclipse's built-in JUnit to classpath
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue