mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-25 17:25:17 +02:00
Merge remote-tracking branch 'origin/GP-6513_ryanmkurtz_headless'
This commit is contained in:
@@ -1028,6 +1028,7 @@ public class HeadlessAnalyzer {
|
||||
|
||||
if (abortProcessing) {
|
||||
Msg.info(this, "Processing aborted as a result of pre-script.");
|
||||
mgr.dispose();
|
||||
return !deleteProgram;
|
||||
}
|
||||
|
||||
@@ -1058,6 +1059,7 @@ public class HeadlessAnalyzer {
|
||||
|
||||
// If no further scripts, just return the current program disposition
|
||||
if (options.postScripts.isEmpty()) {
|
||||
mgr.dispose();
|
||||
return !deleteProgram;
|
||||
}
|
||||
|
||||
@@ -1125,6 +1127,7 @@ public class HeadlessAnalyzer {
|
||||
|
||||
}
|
||||
|
||||
mgr.dispose();
|
||||
return !deleteProgram;
|
||||
}
|
||||
|
||||
@@ -1222,7 +1225,6 @@ public class HeadlessAnalyzer {
|
||||
|
||||
if (options.commit) {
|
||||
|
||||
AutoAnalysisManager.getAnalysisManager(program).dispose();
|
||||
program.release(this);
|
||||
program = null;
|
||||
|
||||
@@ -1255,7 +1257,6 @@ public class HeadlessAnalyzer {
|
||||
finally {
|
||||
|
||||
if (program != null) {
|
||||
AutoAnalysisManager.getAnalysisManager(program).dispose();
|
||||
program.release(this);
|
||||
program = null;
|
||||
}
|
||||
@@ -1415,7 +1416,7 @@ public class HeadlessAnalyzer {
|
||||
return p;
|
||||
}
|
||||
|
||||
private boolean checkOverwrite(Loaded<Program> loaded) throws IOException {
|
||||
private boolean checkOverwrite(Loaded<? extends DomainObject> loaded) throws IOException {
|
||||
DomainFolder folder = project.getProjectData().getFolder(loaded.getProjectFolderPath());
|
||||
if (folder == null) {
|
||||
return true;
|
||||
@@ -1543,7 +1544,7 @@ public class HeadlessAnalyzer {
|
||||
|
||||
// Perform the load.
|
||||
// Note that loading 1 file may result in more than 1 thing getting loaded.
|
||||
LoadResults<Program> loadResults = null;
|
||||
LoadResults<? extends DomainObject> loadResults = null;
|
||||
try {
|
||||
loadResults = ProgramLoader.builder()
|
||||
.source(fsrl)
|
||||
@@ -1554,37 +1555,40 @@ public class HeadlessAnalyzer {
|
||||
.compiler(options.compilerSpec)
|
||||
.loaders(options.loaderClass)
|
||||
.loaderArgs(options.loaderArgs)
|
||||
.load();
|
||||
.loadAll();
|
||||
|
||||
Msg.info(this, "IMPORTING: Loaded " + (loadResults.size() - 1) + " additional files");
|
||||
|
||||
// Make sure we are allowed to save ALL programs to the project. If not, save none and
|
||||
// fail.
|
||||
// Make sure we are allowed to save ALL domain objects to the project.
|
||||
// If not, save none and fail.
|
||||
if (!options.readOnly) {
|
||||
for (Loaded<Program> loaded : loadResults) {
|
||||
for (Loaded<? extends DomainObject> loaded : loadResults) {
|
||||
if (!checkOverwrite(loaded)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there are defined memory blocks in the primary program.
|
||||
// Abort if not (there is nothing to work with!).
|
||||
Loaded<Program> primary = loadResults.getPrimary();
|
||||
if (primary.check(p -> p.getMemory().getAllInitializedAddressSet().isEmpty())) {
|
||||
Msg.error(this, "REPORT: Error: No memory blocks were defined for file " + fsrl);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Analyze the primary program, and determine if we should save.
|
||||
// TODO: Analyze non-primary programs (GP-2965).
|
||||
Program primaryProgram = primary.getDomainObject(this);
|
||||
boolean doSave;
|
||||
boolean doSave = !options.readOnly;
|
||||
Loaded<? extends DomainObject> primary = loadResults.getPrimary();
|
||||
DomainObject primaryDomainObject = primary.getDomainObject(this);
|
||||
try {
|
||||
doSave = analyzeProgram(fsrl.toString(), primaryProgram) && !options.readOnly;
|
||||
if (primaryDomainObject instanceof Program primaryProgram) {
|
||||
// Check if there are defined memory blocks in the primary program.
|
||||
// Abort if not (there is nothing to work with!).
|
||||
if (primaryProgram.getMemory().getAllInitializedAddressSet().isEmpty()) {
|
||||
Msg.error(this,
|
||||
"REPORT: Error: No memory blocks were defined for file " + fsrl);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Analyze the primary program, and determine if we should save.
|
||||
// TODO: Analyze non-primary programs (GP-2965).
|
||||
doSave = analyzeProgram(fsrl.toString(), primaryProgram) && doSave;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
primaryProgram.release(this);
|
||||
primaryDomainObject.release(this);
|
||||
}
|
||||
|
||||
// The act of marking the program as temporary by a script will signal
|
||||
@@ -1605,8 +1609,8 @@ public class HeadlessAnalyzer {
|
||||
}
|
||||
|
||||
// Save
|
||||
for (Loaded<Program> loaded : loadResults) {
|
||||
if (!loaded.check(Program::isTemporary)) {
|
||||
for (Loaded<? extends DomainObject> loaded : loadResults) {
|
||||
if (!loaded.check(DomainObject::isTemporary)) {
|
||||
try {
|
||||
DomainFile domainFile = loaded.save(TaskMonitor.DUMMY);
|
||||
Msg.info(this, String.format("REPORT: Save succeeded for: %s (%s)", loaded,
|
||||
@@ -1630,11 +1634,8 @@ public class HeadlessAnalyzer {
|
||||
|
||||
// Commit changes
|
||||
if (options.commit) {
|
||||
for (Loaded<Program> loaded : loadResults) {
|
||||
if (!loaded.check(Program::isTemporary)) {
|
||||
if (loaded == primary) {
|
||||
AutoAnalysisManager.getAnalysisManager(primaryProgram).dispose();
|
||||
}
|
||||
for (Loaded<? extends DomainObject> loaded : loadResults) {
|
||||
if (!loaded.check(DomainObject::isTemporary)) {
|
||||
loaded.close(); // we need to close before committing
|
||||
commitProgram(loaded.getSavedDomainFile());
|
||||
}
|
||||
|
||||
@@ -464,6 +464,67 @@ public class ProgramLoader {
|
||||
@Deprecated(since = "12.0", forRemoval = true)
|
||||
LoadResults<Program> load(Object consumer) throws IOException, LanguageNotFoundException,
|
||||
CancelledException, VersionException, LoadException {
|
||||
|
||||
LoadResults<? extends DomainObject> loadResults = loadAll(consumer);
|
||||
|
||||
// Filter out and release non-Programs
|
||||
List<Loaded<Program>> loadedPrograms = new ArrayList<>();
|
||||
for (Loaded<? extends DomainObject> loaded : loadResults) {
|
||||
if (Program.class.isAssignableFrom(loaded.getDomainObjectType())) {
|
||||
loadedPrograms.add((Loaded<Program>) loaded);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
loaded.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loadedPrograms.isEmpty()) {
|
||||
throw new LoadException("Domain objects were loaded, but none were Programs");
|
||||
}
|
||||
return new LoadResults<>(loadedPrograms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified {@link #source(ByteProvider) source} with this {@link Builder}'s
|
||||
* current configuration
|
||||
*
|
||||
* @return The {@link LoadResults} which contains one or more {@link Loaded}
|
||||
* {@link DomainObject}s (created but not saved)
|
||||
* @throws IOException if there was an IO-related problem loading
|
||||
* @throws LanguageNotFoundException if there was a problem getting the language
|
||||
* @throws CancelledException if the operation was cancelled
|
||||
* @throws VersionException if there was an issue with database versions, probably due to a
|
||||
* failed language upgrade
|
||||
* @throws LoadException if there was a problem loading
|
||||
*/
|
||||
public LoadResults<? extends DomainObject> loadAll() throws IOException,
|
||||
LanguageNotFoundException, CancelledException, VersionException, LoadException {
|
||||
return loadAll(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified {@link #source(ByteProvider) source} with this {@link Builder}'s
|
||||
* current configuration
|
||||
*
|
||||
* @param consumer A reference to the object "consuming" the returned {@link LoadResults},
|
||||
* used to ensure the underlying {@link DomainObject}s are only closed when every consumer
|
||||
* is done with it (see {@link LoadResults#close()}).
|
||||
* @return The {@link LoadResults} which contains one or more {@link Loaded}
|
||||
* {@link DomainObject}s (created but not saved)
|
||||
* @throws IOException if there was an IO-related problem loading
|
||||
* @throws LanguageNotFoundException if there was a problem getting the language
|
||||
* @throws CancelledException if the operation was cancelled
|
||||
* @throws VersionException if there was an issue with database versions, probably due to a
|
||||
* failed language upgrade
|
||||
* @throws LoadException if there was a problem loading
|
||||
*/
|
||||
@Deprecated(since = "12.1", forRemoval = true)
|
||||
public LoadResults<? extends DomainObject> loadAll(Object consumer) throws IOException,
|
||||
LanguageNotFoundException, CancelledException, VersionException, LoadException {
|
||||
try (ByteProvider p = getSourceAsProvider()) {
|
||||
|
||||
LoadSpec loadSpec = getLoadSpec(p);
|
||||
@@ -501,25 +562,7 @@ public class ProgramLoader {
|
||||
Msg.info(ProgramLoader.class, "Additional info:\n" + log);
|
||||
}
|
||||
|
||||
// Filter out and release non-Programs
|
||||
List<Loaded<Program>> loadedPrograms = new ArrayList<>();
|
||||
for (Loaded<? extends DomainObject> loaded : loadResults) {
|
||||
if (Program.class.isAssignableFrom(loaded.getDomainObjectType())) {
|
||||
loadedPrograms.add((Loaded<Program>) loaded);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
loaded.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loadedPrograms.isEmpty()) {
|
||||
throw new LoadException("Domain objects were loaded, but none were Programs");
|
||||
}
|
||||
return new LoadResults<>(loadedPrograms);
|
||||
return loadResults;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user