mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
Merge branch 'GP-5848_ryanmkurtz_lib-archs'
This commit is contained in:
@@ -38,7 +38,6 @@ import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.Library;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.ExternalManager;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
@@ -632,12 +631,12 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
continue;
|
||||
}
|
||||
processed.add(library);
|
||||
if (findLibraryInProject(library, libraryDestFolder, searchPaths,
|
||||
if (findLibraryInProject(library, libraryDestFolder, searchPaths, true,
|
||||
settings) != null) {
|
||||
log.appendMsg("Found %s in %s...".formatted(library, libraryDestFolder));
|
||||
log.appendMsg("------------------------------------------------\n");
|
||||
}
|
||||
else if (findLibraryInProject(library, linkSearchFolder, searchPaths,
|
||||
else if (findLibraryInProject(library, linkSearchFolder, searchPaths, true,
|
||||
settings) != null) {
|
||||
log.appendMsg("Found %s in %s...".formatted(library, linkSearchFolder));
|
||||
log.appendMsg("------------------------------------------------\n");
|
||||
@@ -779,12 +778,14 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
* @param folder {@link DomainFolder root folder} within which imported libraries will
|
||||
* be searched. If null this method will return null.
|
||||
* @param searchPaths A {@link List} of {@link LibrarySearchPath}s that will be searched
|
||||
* @param matchLoadSpec True if the returned library must match the desired load spec; false
|
||||
* if a match is not required
|
||||
* @param settings The {@link Loader.ImporterSettings}
|
||||
* @return The found {@link DomainFile} or null if not found
|
||||
* @throws CancelledException if the user cancelled the load
|
||||
*/
|
||||
protected DomainFile findLibraryInProject(String library, DomainFolder folder,
|
||||
List<LibrarySearchPath> searchPaths, ImporterSettings settings)
|
||||
List<LibrarySearchPath> searchPaths, boolean matchLoadSpec, ImporterSettings settings)
|
||||
throws CancelledException {
|
||||
if (folder == null) {
|
||||
return null;
|
||||
@@ -809,7 +810,8 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
}
|
||||
DomainFile ret =
|
||||
lookupLibraryInFolder(FilenameUtils.getName(library), parentFolder);
|
||||
if (ret != null) {
|
||||
if (ret != null &&
|
||||
(!matchLoadSpec || matchSupportedLoadSpec(settings.loadSpec(), ret))) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -825,13 +827,19 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
}
|
||||
}
|
||||
|
||||
// First perform a direct filename lookup in the folder (for efficiency)
|
||||
String libraryName = FilenameUtils.getName(library);
|
||||
DomainFile file = folder.getFile(libraryName);
|
||||
if (file != null) {
|
||||
return file;
|
||||
return !matchLoadSpec || matchSupportedLoadSpec(settings.loadSpec(), file) ? file
|
||||
: null;
|
||||
}
|
||||
|
||||
return lookupLibraryInFolder(libraryName, folder);
|
||||
// If necessary, perform a slower comparator-based lookup on every file in the folder
|
||||
file = lookupLibraryInFolder(libraryName, folder);
|
||||
return file != null && (!matchLoadSpec || matchSupportedLoadSpec(settings.loadSpec(), file))
|
||||
? file
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -968,40 +976,50 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
continue;
|
||||
}
|
||||
monitor.checkCancelled();
|
||||
try {
|
||||
Loaded<Program> match = findLibraryInLoadedList(loadedPrograms, externalLibName);
|
||||
if (match != null) {
|
||||
extManager.setExternalPath(externalLibName, FSUtilities
|
||||
.appendPath(match.getProjectFolderPath(), match.getName()),
|
||||
false);
|
||||
log.appendMsg(" [" + externalLibName + "] -> [" + match.getName() + "]");
|
||||
setExternalLibrary(externalLibName,
|
||||
FSUtilities.appendPath(match.getProjectFolderPath(), match.getName()), program,
|
||||
settings);
|
||||
}
|
||||
else {
|
||||
boolean found = false;
|
||||
for (DomainFolder searchFolder : searchFolders) {
|
||||
DomainFile alreadyImportedLib = findLibraryInProject(externalLibName,
|
||||
searchFolder, fsSearchPaths, settings);
|
||||
searchFolder, fsSearchPaths, false, settings);
|
||||
if (alreadyImportedLib != null) {
|
||||
extManager.setExternalPath(externalLibName,
|
||||
alreadyImportedLib.getPathname(), false);
|
||||
log.appendMsg(" [" + externalLibName + "] -> [" +
|
||||
alreadyImportedLib.getPathname() + "] (previously imported)");
|
||||
if (matchSupportedLoadSpec(settings.loadSpec(), alreadyImportedLib)) {
|
||||
setExternalLibrary(externalLibName, alreadyImportedLib.getPathname(),
|
||||
program, settings);
|
||||
}
|
||||
else {
|
||||
log.appendMsg(
|
||||
" [%s] -> found wrong architecture".formatted(externalLibName));
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
log.appendMsg(" [" + externalLibName + "] -> not found in project");
|
||||
log.appendMsg(" [%s] -> not found in project".formatted(externalLibName));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.error(this, "Bad library name: " + externalLibName, e);
|
||||
}
|
||||
}
|
||||
log.appendMsg("------------------------------------------------\n");
|
||||
}
|
||||
|
||||
private void setExternalLibrary(String libraryName, String pathname, Program program,
|
||||
ImporterSettings settings) {
|
||||
MessageLog log = settings.log();
|
||||
try {
|
||||
program.getExternalManager().setExternalPath(libraryName, pathname, false);
|
||||
log.appendMsg(" [%s] -> [%s] (previously imported)".formatted(libraryName, pathname));
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
log.appendMsg(" [%s] -> bad library name".formatted(libraryName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A library that has not been processed by the loader yet
|
||||
*
|
||||
@@ -1175,6 +1193,28 @@ public abstract class AbstractLibrarySupportLoader extends AbstractProgramLoader
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return whether or not the given {@link LoadSpec} matches the one associated with the given
|
||||
* {@link DomainFile}}
|
||||
* <p>
|
||||
* To avoid having to open each library which might require an upgrade, we just look at the
|
||||
* "Language ID" metadata attached to the {@link DomainFile}.
|
||||
*
|
||||
* @param desiredLoadSpec The desired {@link LoadSpec}
|
||||
* @param df The {@link DomainFile}
|
||||
*/
|
||||
protected boolean matchSupportedLoadSpec(LoadSpec desiredLoadSpec, DomainFile df) {
|
||||
String fileLangId = df.getMetadata().getOrDefault("Language ID", "");
|
||||
String desiredLangId =
|
||||
desiredLoadSpec.getLanguageCompilerSpec().getLanguageID().getIdAsString();
|
||||
|
||||
String[] fileParts = fileLangId.split(":");
|
||||
String[] desiredParts = desiredLangId.split(":");
|
||||
|
||||
return fileParts.length >= 3 && desiredParts.length >= 3 &&
|
||||
Arrays.equals(fileParts, 0, 3, desiredParts, 0, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks in the given {@link GFileSystem} for the given library using the loader's
|
||||
* {@link #getLibraryNameComparator() library name comparator}
|
||||
|
||||
@@ -627,7 +627,7 @@ public class MachoLoader extends AbstractLibrarySupportLoader {
|
||||
if (lib == null) {
|
||||
for (DomainFolder searchFolder : searchFolders) {
|
||||
DomainFile df =
|
||||
findLibraryInProject(path, searchFolder, searchPaths, settings);
|
||||
findLibraryInProject(path, searchFolder, searchPaths, true, settings);
|
||||
if (df != null) {
|
||||
DomainObject obj = df.getDomainObject(this, true, true, monitor);
|
||||
if (obj instanceof Program p) {
|
||||
|
||||
Reference in New Issue
Block a user