GP-2877: Refactoring Loader and AutoImporter to better accommodate loading more than one thing

This commit is contained in:
Ryan Kurtz
2023-02-13 16:58:30 -05:00
parent 65e2c720b4
commit 1574262722
40 changed files with 2049 additions and 1300 deletions

View File

@@ -17,7 +17,8 @@
//@category FunctionID
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.function.Predicate;
import ghidra.app.script.GhidraScript;
@@ -26,9 +27,9 @@ import ghidra.app.util.bin.format.coff.*;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
import ghidra.app.util.importer.*;
import ghidra.app.util.opinion.Loader;
import ghidra.app.util.opinion.MSCoffLoader;
import ghidra.app.util.opinion.*;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.program.model.lang.LanguageDescription;
import ghidra.program.model.listing.Program;
@@ -95,41 +96,44 @@ public class ImportMSLibs extends GhidraScript {
}
offsetsSeen.add(archiveMemberHeader.getPayloadOffset());
if (archiveMemberHeader.isCOFF()) {
String preferredName = archiveMemberHeader.getName();
try (ByteProvider coffProvider = new ByteProviderWrapper(provider,
archiveMemberHeader.getPayloadOffset(), archiveMemberHeader.getSize())) {
CoffFileHeader header = new CoffFileHeader(coffProvider);
if (CoffMachineType.isMachineTypeDefined(header.getMagic())) {
String preferredName = archiveMemberHeader.getName();
String[] splits = splitPreferredName(preferredName);
List<Program> programs =
LoadResults<? extends DomainObject> loadResults =
AutoImporter.importFresh(
coffProvider,
root,
state.getProject(),
root.getPathname(),
this,
log,
new CancelOnlyWrappingTaskMonitor(monitor),
LOADER_FILTER,
LOADSPEC_CHOOSER,
mangleNameBecauseDomainFoldersAreSoRetro(splits[splits.length - 1]),
OptionChooser.DEFAULT_OPTIONS,
MultipleProgramsStrategy.ONE_PROGRAM_OR_EXCEPTION);
OptionChooser.DEFAULT_OPTIONS);
if (programs == null || programs.isEmpty()) {
printerr("no programs loaded from " + file + " - " +
preferredName);
}
if (programs != null) {
for (Program program : programs) {
program.release(this);
DomainFolder destination =
establishFolder(root, file, program, isDebug, splits);
program.getDomainFile().moveTo(destination);
try {
for (Loaded<? extends DomainObject> loaded : loadResults) {
if (loaded.getDomainObject() instanceof Program program) {
loaded.save(state.getProject(), log, monitor);
DomainFolder destination =
establishFolder(root, file, program, isDebug, splits);
program.getDomainFile().moveTo(destination);
}
}
}
finally {
loadResults.release(this);
}
}
}
catch (LoadException e) {
printerr("no programs loaded from " + file + " - " + preferredName);
}
}
}
}

View File

@@ -64,10 +64,8 @@ import ghidra.app.util.bin.format.coff.*;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
import ghidra.app.util.importer.*;
import ghidra.app.util.opinion.Loader;
import ghidra.app.util.opinion.MSCoffLoader;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainFolder;
import ghidra.app.util.opinion.*;
import ghidra.framework.model.*;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.program.model.listing.Program;
import ghidra.util.InvalidNameException;
@@ -198,24 +196,30 @@ public class MSLibBatchImportWorker extends GhidraScript {
Pair<DomainFolder, String> pair =
getFolderAndUniqueFile(currentLibraryFolder, preferredName);
LoadResults<? extends DomainObject> loadResults = null;
try {
loadResults = AutoImporter.importFresh(coffProvider,
state.getProject(), pair.first.getPathname(), this, log,
monitor, LOADER_FILTER, LOADSPEC_CHOOSER, pair.second,
OptionChooser.DEFAULT_OPTIONS);
List<Program> programs = AutoImporter.importFresh(coffProvider,
pair.first, this, log, monitor, LOADER_FILTER, LOADSPEC_CHOOSER,
pair.second, OptionChooser.DEFAULT_OPTIONS,
MultipleProgramsStrategy.ONE_PROGRAM_OR_EXCEPTION);
for (Loaded<? extends DomainObject> loaded : loadResults) {
if (loaded.getDomainObject() instanceof Program program) {
loaded.save(state.getProject(), log, monitor);
println(
"Imported " + program.getDomainFile().getPathname());
DomainFile progFile = program.getDomainFile();
if (programs != null) {
for (Program program : programs) {
println("Imported " + program.getDomainFile().getPathname());
DomainFile progFile = program.getDomainFile();
program.release(this);
if (!progFile.isVersioned()) {
progFile.addToVersionControl(initalCheckInComment, false,
monitor);
if (!progFile.isVersioned()) {
progFile.addToVersionControl(initalCheckInComment,
false, monitor);
}
}
}
}
finally {
if (loadResults != null) {
loadResults.release(this);
}
}
}

View File

@@ -15,7 +15,8 @@
*/
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.function.Predicate;
import generic.stl.Pair;
@@ -25,11 +26,10 @@ import ghidra.app.util.bin.format.coff.*;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveHeader;
import ghidra.app.util.bin.format.coff.archive.CoffArchiveMemberHeader;
import ghidra.app.util.importer.*;
import ghidra.app.util.opinion.Loader;
import ghidra.app.util.opinion.MSCoffLoader;
import ghidra.app.util.opinion.*;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.program.model.listing.Program;
import ghidra.util.InvalidNameException;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
@@ -152,16 +152,18 @@ public class RecursiveRecursiveMSLibImport extends GhidraScript {
Pair<DomainFolder, String> pair =
establishProgramFolder(currentLibrary, preferredName);
List<Program> programs = AutoImporter.importFresh(coffProvider,
pair.first, this, log, monitor, LOADER_FILTER, LOADSPEC_CHOOSER,
mangleNameBecauseDomainFoldersAreSoRetro(pair.second),
OptionChooser.DEFAULT_OPTIONS,
MultipleProgramsStrategy.ONE_PROGRAM_OR_EXCEPTION);
LoadResults<? extends DomainObject> loadResults =
AutoImporter.importFresh(coffProvider, state.getProject(),
pair.first.getPathname(), this, log, monitor, LOADER_FILTER,
LOADSPEC_CHOOSER,
mangleNameBecauseDomainFoldersAreSoRetro(pair.second),
OptionChooser.DEFAULT_OPTIONS);
if (programs != null) {
for (Program program : programs) {
program.release(this);
}
try {
loadResults.save(state.getProject(), this, log, monitor);
}
finally {
loadResults.release(this);
}
}
}