Merge branch 'GP-1525_ghidra1_ExternalFunctionPrimary' into Ghidra_10.1

This commit is contained in:
ghidra1 2021-11-23 21:44:26 -05:00
commit 5c82f87905
18 changed files with 553 additions and 433 deletions

View file

@ -87,9 +87,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
}
}
/**
* @see ghidra.program.database.ManagerDB#setProgram(ghidra.program.database.ProgramDB)
*/
@Override
public void setProgram(ProgramDB program) {
this.program = program;
@ -98,9 +95,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
scopeMgr = program.getNamespaceManager();
}
/**
* @see ghidra.program.database.ManagerDB#programReady(int, int, ghidra.util.task.TaskMonitor)
*/
@Override
public void programReady(int openMode, int currentRevision, TaskMonitor monitor)
throws IOException, CancelledException {
@ -185,26 +179,17 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return true;
}
/**
* @see ghidra.program.database.ManagerDB#invalidateCache(boolean)
*/
@Override
public void invalidateCache(boolean all) throws IOException {
// nothing to do here
}
/**
* @see ghidra.program.database.ManagerDB#deleteAddressRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.util.task.TaskMonitor)
*/
@Override
public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor)
throws CancelledException {
// Has no affect on externals
}
/**
* @see ghidra.program.database.ManagerDB#moveAddressRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, long, ghidra.util.task.TaskMonitor)
*/
@Override
public void moveAddressRange(Address fromAddr, Address toAddr, long length, TaskMonitor monitor)
throws CancelledException {
@ -230,8 +215,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
@Override
public ExternalLocation addExtLocation(Namespace extParentNamespace, String extLabel,
Address extAddr, SourceType sourceType)
throws InvalidInputException, DuplicateNameException {
Address extAddr, SourceType sourceType) throws InvalidInputException {
lock.acquire();
try {
return addExtLocation(extParentNamespace, extLabel, extAddr, false, sourceType, true);
@ -243,8 +227,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
@Override
public ExternalLocation addExtLocation(Namespace extParentNamespace, String extLabel,
Address extAddr, SourceType sourceType, boolean reuseExisting)
throws InvalidInputException, DuplicateNameException {
Address extAddr, SourceType sourceType, boolean reuseExisting) throws InvalidInputException {
lock.acquire();
try {
return addExtLocation(extParentNamespace, extLabel, extAddr, false, sourceType,
@ -275,8 +258,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
@Override
public ExternalLocation addExtFunction(Namespace extParentNamespace, String extLabel,
Address extAddr, SourceType sourceType)
throws InvalidInputException, DuplicateNameException {
Address extAddr, SourceType sourceType) throws InvalidInputException {
lock.acquire();
try {
return addExtLocation(extParentNamespace, extLabel, extAddr, true, sourceType, true);
@ -288,9 +270,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
@Override
public ExternalLocation addExtFunction(Namespace extNamespace, String extLabel, Address extAddr,
SourceType sourceType, boolean reuseExisting)
throws InvalidInputException, DuplicateNameException {
SourceType sourceType, boolean reuseExisting) throws InvalidInputException {
lock.acquire();
try {
return addExtLocation(extNamespace, extLabel, extAddr, true, sourceType, reuseExisting);
@ -314,11 +294,18 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
private ExternalLocation addExtLocation(Namespace extNamespace, String extLabel,
Address extAddr, boolean isFunction, SourceType sourceType, boolean reuseExisting)
throws InvalidInputException, DuplicateNameException {
throws InvalidInputException {
if (extNamespace == null) {
extNamespace = getLibraryScope(Library.UNKNOWN);
if (extNamespace == null) {
extNamespace = addExternalLibraryName(Library.UNKNOWN, SourceType.ANALYSIS);
try {
extNamespace = addExternalLibraryName(Library.UNKNOWN, SourceType.ANALYSIS);
}
catch (DuplicateNameException e) {
// TODO: really need to reserve the unknown namespace name
throw new InvalidInputException(
"Failed to establish " + Library.UNKNOWN + " library");
}
}
}
else if (!extNamespace.isExternal()) {
@ -637,9 +624,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return symbolMgr;
}
/**
* @see ghidra.program.model.symbol.ExternalManager#removeExternalLibrary(java.lang.String)
*/
@Override
public boolean removeExternalLibrary(String name) {
lock.acquire();
@ -694,8 +678,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
private Library addExternalName(String name, String pathname, SourceType source)
throws DuplicateNameException, InvalidInputException {
SymbolDB s = symbolMgr.createSpecialSymbol(Address.NO_ADDRESS, name,
scopeMgr.getGlobalNamespace(), SymbolType.LIBRARY, null, null, pathname, source);
SymbolDB s = symbolMgr.createLibrarySymbol(name, pathname, source);
return (Library) s.getObject();
}
@ -704,17 +687,11 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return s == null ? null : (Namespace) s.getObject();
}
/**
* @see ghidra.program.model.symbol.ExternalManager#contains(java.lang.String)
*/
@Override
public boolean contains(String libraryName) {
return symbolMgr.getLibrarySymbol(libraryName) != null;
}
/**
* @see ghidra.program.model.symbol.ExternalManager#getExternalLibraryNames()
*/
@Override
public String[] getExternalLibraryNames() {
ArrayList<String> list = new ArrayList<>();
@ -735,9 +712,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return s != null ? (Library) s.getObject() : null;
}
/**
* @see ghidra.program.model.symbol.ExternalManager#getExternalLibraryPath(java.lang.String)
*/
@Override
public String getExternalLibraryPath(String externalName) {
SymbolDB s = (SymbolDB) symbolMgr.getLibrarySymbol(externalName);
@ -799,7 +773,7 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
try {
SymbolDB symbol = (SymbolDB) extLoc.getSymbol();
if (!(symbol instanceof CodeSymbol)) {
return null;
throw new IllegalStateException("Expected external code symbol");
}
//long dtId = symbol.getSymbolData1();
String extData = symbol.getSymbolStringData();
@ -813,18 +787,13 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return functionMgr.createExternalFunction(extAddr, name, namespace, extData, source);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unexpected exception", e);
}
finally {
lock.release();
}
}
/**
* @return
*/
AddressMap getAddressMap() {
return addrMap;
}
@ -834,9 +803,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return new ExternalLocationDBIterator(symbolMgr.getExternalSymbols(), memoryAddress);
}
/**
* @see ghidra.program.model.symbol.ExternalManager#getExternalLocations(java.lang.String)
*/
@Override
public ExternalLocationIterator getExternalLocations(String externalName) {
Namespace scope = getLibraryScope(externalName);
@ -864,9 +830,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
this.symIter = symIter;
}
/**
* @see java.util.Iterator#remove()
*/
@Override
public void remove() {
throw new UnsupportedOperationException();
@ -888,9 +851,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return null;
}
/**
* @see ghidra.program.model.symbol.ExternalLocationIterator#hasNext()
*/
@Override
public boolean hasNext() {
if (symIter != null) {
@ -902,9 +862,6 @@ public class ExternalManagerDB implements ManagerDB, ExternalManager {
return nextExtLoc != null;
}
/**
* @see ghidra.program.model.symbol.ExternalLocationIterator#next()
*/
@Override
public ExternalLocation next() {
if (hasNext()) {

View file

@ -272,23 +272,23 @@ public class FunctionManagerDB implements FunctionManager {
/**
* Transform an existing external symbol into an external function.
* This method should only be invoked by an ExternalSymbol
* @param extSpaceAddr the external space address to use when creating this external.
* @param extSpaceAddr the external space address to use when creating this external. Any
* other symbol using this address must first be deleted. Results are unpredictable if this is
* not done.
* @param name the external function name
* @param nameSpace the external function namespace
* @param extData the external data string to store additional info (see {@link ExternalLocationDB})
* @param source the source of this external.
* @return external function
* @throws InvalidInputException if the name is invalid
* @throws DuplicateNameException if the name is an invalid duplicate
*/
public Function createExternalFunction(Address extSpaceAddr, String name, Namespace nameSpace,
String extData, SourceType source)
throws DuplicateNameException, InvalidInputException {
throws InvalidInputException {
lock.acquire();
try {
Symbol symbol = symbolMgr.createSpecialSymbol(extSpaceAddr, name, nameSpace,
SymbolType.FUNCTION, null, null, extData, source);
Symbol symbol =
symbolMgr.createFunctionSymbol(extSpaceAddr, name, nameSpace, source, extData);
long returnDataTypeId = program.getDataTypeManager().getResolvedID(DataType.DEFAULT);

View file

@ -1115,6 +1115,17 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
}
@Override
public void removeAllReferencesTo(Address toAddr) {
try {
removeAllTo(toAddr);
}
catch (IOException e) {
program.dbError(e);
}
}
void removeReference(Address fromAddr, Address toAddr, int opIndex) {
lock.acquire();
try {

View file

@ -85,18 +85,22 @@ public class CodeSymbol extends SymbolDB {
@Override
public boolean delete() {
if (isExternal()) {
return delete(false);
}
return super.delete();
boolean keepReferences = !isExternal();
return delete(keepReferences);
}
/**
* Delete code/label symbol
* @param keepReferences if false all references to this symbols address will be removed,
* otherwise associated references will simply be disassociated following symbol removal
* (see {@link SymbolManager#doRemoveSymbol(SymbolDB)}.
* @return true if symbol successfully removed
*/
public boolean delete(boolean keepReferences) {
lock.acquire();
try {
if (!keepReferences) {
// remove external references
removeAllReferencesTo();
symbolMgr.getReferenceManager().removeAllReferencesTo(getAddress());
}
return super.delete();
}

View file

@ -20,7 +20,6 @@ import java.util.List;
import db.DBRecord;
import ghidra.program.database.DBObjectCache;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.external.ExternalManagerDB;
import ghidra.program.database.function.FunctionManagerDB;
import ghidra.program.model.address.Address;
@ -91,9 +90,6 @@ public class FunctionSymbol extends SymbolDB {
}
}
/**
* @see ghidra.program.model.symbol.Symbol#delete()
*/
@Override
public boolean delete() {
lock.acquire();
@ -120,7 +116,8 @@ public class FunctionSymbol extends SymbolDB {
boolean restored = createLabelForDeletedFunctionName(address, symName, extData,
namespace, source, pinned);
if (!restored && isExternal()) {
removeAllReferencesTo();
// remove all associated external references if label not restored
symbolMgr.getReferenceManager().removeAllReferencesTo(getAddress());
}
}
return true;
@ -138,34 +135,19 @@ public class FunctionSymbol extends SymbolDB {
*/
private boolean createLabelForDeletedFunctionName(Address entryPoint, String symName,
String stringData, Namespace namespace, SourceType source, boolean pinned) {
if (isExternal()) {
SymbolDB parent = (SymbolDB) namespace.getSymbol();
if (parent.isDeleting()) {
return false; // don't recreate external
}
Symbol parentSymbol = namespace.getSymbol();
if ((parentSymbol instanceof SymbolDB) && ((SymbolDB) parentSymbol).isDeleting()) {
// do not replace function with label if parent namespace is getting removed
return false;
}
try {
SymbolDB newSym;
try {
newSym = symbolMgr.createSpecialSymbol(entryPoint, symName, namespace,
SymbolType.LABEL, null, null, stringData, source);
if (pinned) {
newSym.setPinned(true);
}
}
catch (InvalidInputException e) {
ProgramDB program = symbolMgr.getProgram();
newSym = (SymbolDB) symbolMgr.createLabel(entryPoint, symName,
program.getGlobalNamespace(), source);
}
newSym.setSymbolStringData(stringData);
Symbol newSym =
symbolMgr.createCodeSymbol(entryPoint, symName, namespace, source, stringData);
newSym.setPrimary();
return true;
}
catch (DuplicateNameException e) {
// This should't happen.
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}
catch (InvalidInputException e) {
// This shouldn't happen.
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
@ -173,17 +155,11 @@ public class FunctionSymbol extends SymbolDB {
return false;
}
/**
* @see ghidra.program.model.symbol.Symbol#getObject()
*/
@Override
public Object getObject() {
return functionMgr.getFunction(key);
}
/**
* @see ghidra.program.model.symbol.Symbol#isPrimary()
*/
@Override
public boolean isPrimary() {
return true;
@ -204,9 +180,6 @@ public class FunctionSymbol extends SymbolDB {
}
}
/**
* @see ghidra.program.model.symbol.Symbol#getProgramLocation()
*/
@Override
public ProgramLocation getProgramLocation() {
lock.acquire();
@ -224,9 +197,6 @@ public class FunctionSymbol extends SymbolDB {
}
}
/**
* @see ghidra.program.model.symbol.Symbol#isValidParent(ghidra.program.model.symbol.Namespace)
*/
@Override
public boolean isValidParent(Namespace parent) {
return SymbolType.FUNCTION.isValidParent(symbolMgr.getProgram(), parent, address,

View file

@ -855,15 +855,6 @@ public abstract class SymbolDB extends DatabaseObject implements Symbol {
}
}
protected void removeAllReferencesTo() {
ReferenceManager refMgr = symbolMgr.getReferenceManager();
ReferenceIterator it = refMgr.getReferencesTo(address);
while (it.hasNext()) {
Reference ref = it.next();
refMgr.delete(ref);
}
}
public long getDataTypeId() {
lock.acquire();
try {

View file

@ -2498,8 +2498,8 @@ public class SymbolManager implements SymbolTable, ManagerDB {
try {
source = adjustSourceTypeIfNecessary(name, type, source, storage);
Address varAddr = variableStorageMgr.getVariableStorageAddress(storage, true);
return (VariableSymbolDB) createSpecialSymbol(varAddr, name, namespace, type,
null, Integer.valueOf(firstUseOffsetOrOrdinal), null, source);
return (VariableSymbolDB) doCreateSpecialSymbol(varAddr, name, namespace, type, null,
Integer.valueOf(firstUseOffsetOrOrdinal), null, source, true);
}
catch (IOException e) {
dbError(e);
@ -2525,29 +2525,21 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override
public GhidraClass createClass(Namespace parent, String name, SourceType source)
throws DuplicateNameException, InvalidInputException {
SymbolDB s =
createSpecialSymbol(Address.NO_ADDRESS, name, parent, SymbolType.CLASS, null, null,
null, source);
SymbolDB s = createClassSymbol(name, parent, source, true);
return new GhidraClassDB(s, namespaceMgr);
}
@Override
public Library createExternalLibrary(String name, SourceType source)
throws DuplicateNameException, InvalidInputException {
SymbolDB s =
createSpecialSymbol(Address.NO_ADDRESS, name, null, SymbolType.LIBRARY, null, null,
null, source);
SymbolDB s = createLibrarySymbol(name, null, source);
return new LibraryDB(s, namespaceMgr);
}
@Override
public Namespace createNameSpace(Namespace parent, String name, SourceType source)
throws DuplicateNameException, InvalidInputException {
SymbolDB s =
createSpecialSymbol(Address.NO_ADDRESS, name, parent, SymbolType.NAMESPACE, null,
null, null, source);
SymbolDB s = createNamespaceSymbol(name, parent, source, true);
return new NamespaceDB(s, namespaceMgr);
}
@ -2569,10 +2561,8 @@ public class SymbolManager implements SymbolTable, ManagerDB {
// no duplicate check, since this class name will be set to that of the existing namespace
String tempName = "_temp_" + System.nanoTime();
SymbolDB classSymbol =
doCreateSpecialSymbol(Address.NO_ADDRESS, tempName, namespace.getParentNamespace(),
SymbolType.CLASS, null, null, null, originalSource,
false /*check for duplicate */);
SymbolDB classSymbol = createClassSymbol(tempName, namespace.getParentNamespace(),
originalSource, false /*check for duplicate */);
GhidraClassDB classNamespace = new GhidraClassDB(classSymbol, namespaceMgr);
// move everything from old namespace into new class namespace
@ -2646,11 +2636,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
// Note: We know there are no namespaces with the name; do we still have to check for
// duplicates? Assuming yes, as another symbol type may exist with this name.
SymbolDB s =
doCreateSpecialSymbol(Address.NO_ADDRESS, name, parent, SymbolType.NAMESPACE, null,
null, null, source, true /*check for duplicates*/);
return new NamespaceDB(s, namespaceMgr);
SymbolDB s = createNamespaceSymbol(name, parent, source, true /*check for duplicates*/);
return new NamespaceDB(s, namespaceMgr);
}
finally {
lock.release();
@ -2658,36 +2646,55 @@ public class SymbolManager implements SymbolTable, ManagerDB {
}
/**
* Creates a symbol, specifying all information for the record. This method is not on the
* public interface and is only intended for program API internal use. The user of this
* method must carefully provided exactly the information needed depending on the type of symbol
* being created.
* @param addr the address for the symbol
* @param name the name of the symbol
* @param parent the namespace for the symbol
* @param symbolType the type of the symbol
* @param dataTypeId the id for an associated datatype or null
* @param variableOffset this is the ordinal for params and firstUseOffset for locals
* @param stringData value whose meaning depends on the symbol type.
* @param source the SourceType for the new symbol
* @return the newly created symbol
* @throws DuplicateNameException if the symbol type must be unique and another already has that name
* in the given namespace.
* @throws InvalidInputException if the name contains any illegal characters (i.e. space)
* Create a Library symbol with the specified name and optional pathname
* @param name library name
* @param pathname project file path (may be null)
* @param source symbol source
* @return library symbol
* @throws DuplicateNameException if library name conflicts with another symbol
* @throws InvalidInputException
*/
public SymbolDB createSpecialSymbol(Address addr, String name, Namespace parent,
SymbolType symbolType, Long dataTypeId, Integer variableOffset, String stringData,
SourceType source)
public SymbolDB createLibrarySymbol(String name, String pathname, SourceType source)
throws DuplicateNameException, InvalidInputException {
return doCreateSpecialSymbol(Address.NO_ADDRESS, name, null, SymbolType.LIBRARY, null, null,
pathname, source, true);
}
return doCreateSpecialSymbol(addr, name, parent, symbolType, stringData, dataTypeId,
variableOffset, source, true);
/**
* Create a Class symbol with the specified name and parent
* @param name class name
* @param parent parent namespace (may be null for global namespace)
* @param source symbol source
* @param checkForDuplicates true if check for duplicate name conflict should be performed
* @return class symbol
* @throws DuplicateNameException if class name conflicts with another symbol
* @throws InvalidInputException
*/
SymbolDB createClassSymbol(String name, Namespace parent, SourceType source,
boolean checkForDuplicates) throws DuplicateNameException, InvalidInputException {
return doCreateSpecialSymbol(Address.NO_ADDRESS, name, parent, SymbolType.CLASS, null, null,
null, source, true);
}
/**
* Create a simple Namespace symbol with the specified name and parent
* @param name class name
* @param parent parent namespace (may be null for global namespace)
* @param source symbol source
* @param checkForDuplicates true if check for duplicate name conflict should be performed
* @return namespace symbol
* @throws DuplicateNameException if namespace name conflicts with another symbol
* @throws InvalidInputException
*/
SymbolDB createNamespaceSymbol(String name, Namespace parent, SourceType source,
boolean checkForDuplicates) throws DuplicateNameException, InvalidInputException {
return doCreateSpecialSymbol(Address.NO_ADDRESS, name, parent, SymbolType.NAMESPACE, null,
null, null, source, true);
}
private SymbolDB doCreateSpecialSymbol(Address addr, String name, Namespace parent,
SymbolType symbolType, String stringData, Long dataTypeId, Integer variableOffset,
SourceType source,
boolean checkForDuplicates)
SymbolType symbolType, Long dataTypeId, Integer variableOffset, String stringData,
SourceType source, boolean checkForDuplicates)
throws DuplicateNameException, InvalidInputException {
lock.acquire();
@ -2722,8 +2729,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
}
/**
* Internal method for creating label symbols.
* @param addr the address for the new symbol
* Internal method for creating label symbols. If identical memory symbol already exists
* it will be returned.
* @param addr the address for the new symbol (memory or external)
* @param name the name of the new symbol
* @param namespace the namespace for the new symbol
* @param source the SourceType of the new symbol
@ -2739,24 +2747,38 @@ public class SymbolManager implements SymbolTable, ManagerDB {
source = validateSource(source, name, addr, SymbolType.LABEL);
name = validateName(name, source);
Symbol symbol = getSymbol(name, addr, namespace);
if (symbol != null) {
return symbol;
}
boolean makePrimary = true;
if (addr.isMemoryAddress()) {
// If there is a default named function, rename it to the new symbol name
Symbol functionSymbol = tryUpdatingDefaultFunction(addr, name, namespace, source);
if (functionSymbol != null) {
return functionSymbol;
}
Symbol symbol = getSymbol(name, addr, namespace);
if (symbol != null) {
return symbol;
}
// if there is a dynamic symbol, delete it and make the new symbol primary.
Symbol primary = getPrimarySymbol(addr);
if (primary != null && primary.isDynamic()) {
deleteDynamicSymbol(primary);
primary = null;
// If there is a default named function, rename it to the new symbol name
Symbol functionSymbol = tryUpdatingDefaultFunction(addr, name, namespace, source);
if (functionSymbol != null) {
return functionSymbol;
}
// if there is a dynamic symbol, delete it and make the new symbol primary.
Symbol primary = getPrimarySymbol(addr);
if (primary != null && primary.isDynamic()) {
deleteDynamicSymbol(primary);
primary = null;
}
makePrimary = (primary == null);
}
else if (addr.isExternalAddress()) {
// only one symbol per external address is allowed
Symbol primary = getPrimarySymbol(addr);
if (primary != null) {
throw new IllegalArgumentException("external address already used");
}
}
else {
throw new IllegalArgumentException("bad label address");
}
boolean makePrimary = primary == null;
return doCreateSymbol(name, addr, namespace, SymbolType.LABEL, stringData, null, null,
source, makePrimary);
@ -2784,6 +2806,27 @@ public class SymbolManager implements SymbolTable, ManagerDB {
source = validateSource(source, name, addr, SymbolType.FUNCTION);
name = validateName(name, source);
if (addr.isMemoryAddress()) {
return doCreateMemoryFunctionSymbol(addr, name, namespace, source, stringData);
}
else if (addr.isExternalAddress()) {
// only one symbol per external address is allowed
Symbol primary = getPrimarySymbol(addr);
if (primary != null) {
throw new IllegalArgumentException("external address already used");
}
}
else {
throw new IllegalArgumentException("bad function address");
}
return doCreateSymbol(name, addr, namespace, SymbolType.FUNCTION, stringData, null, null,
source, true);
}
private Symbol doCreateMemoryFunctionSymbol(Address addr, String name, Namespace namespace,
SourceType source, String stringData) throws InvalidInputException {
// if there is already a FUNCTION symbol with that name and namespace here, just return it.
Symbol matching = getSymbol(name, addr, namespace);
if (matching != null && matching.getSymbolType() == SymbolType.FUNCTION) {

View file

@ -30,29 +30,31 @@ import ghidra.util.exception.InvalidInputException;
public interface ExternalManager {
/**
* Returns a list of all external names for which locations have been defined.
* Returns an array of all external names for which locations have been defined.
* @return array of external names
*/
public String[] getExternalLibraryNames();
/**
* Get the Library which corresponds to the specified name
* @param name name of library
* @param libraryName name of library
* @return library or null if not found
*/
public Library getExternalLibrary(String name);
public Library getExternalLibrary(String libraryName);
/**
* Removes external name if no associated ExternalLocation's exist
* @param name external name
* @param libraryName external library name
* @return true if removed, false if unable to due to associated locations/references
*/
public boolean removeExternalLibrary(String name);
public boolean removeExternalLibrary(String libraryName);
/**
* Returns the file pathname associated with an external name.
* Null is returned if either the external name does not exist or
* a pathname has not been set.
* @param libraryName external name
* @return project file pathname or null
*/
public String getExternalLibraryPath(String libraryName);
@ -61,6 +63,7 @@ public interface ExternalManager {
* @param libraryName the name of the library to associate with a file.
* @param pathname the path to the program to be associated with the library name.
* @param userDefined true if the external path is being specified by the user
* @throws InvalidInputException
*/
public void setExternalPath(String libraryName, String pathname, boolean userDefined)
throws InvalidInputException;
@ -70,6 +73,8 @@ public interface ExternalManager {
* @param oldName the old name of the external library name.
* @param newName the new name of the external library name.
* @param source the source of this external library
* @throws DuplicateNameException if another namespace has the same name
* @throws InvalidInputException
*/
public void updateExternalLibraryName(String oldName, String newName, SourceType source)
throws DuplicateNameException, InvalidInputException;
@ -85,7 +90,7 @@ public interface ExternalManager {
/**
* Get an iterator over all external locations which have been associated to
* the specified memory address
* @param memoryAddress
* @param memoryAddress memory address
* @return external location iterator
*/
public ExternalLocationIterator getExternalLocations(Address memoryAddress);
@ -94,7 +99,9 @@ public interface ExternalManager {
* Get an external location.
* @param libraryName the name of the library for which to get an external location
* @param label the name of the external location.
* @deprecated Use {@link #getExternalLocations(String, String)} instead
* @return first matching external location
* @deprecated Use {@link #getExternalLocations(String, String)} or
* {@link #getUniqueExternalLocation(String, String)} since duplicate names may exist
*/
@Deprecated
public ExternalLocation getExternalLocation(String libraryName, String label);
@ -103,7 +110,9 @@ public interface ExternalManager {
* Get an external location.
* @param namespace the namespace containing the external label.
* @param label the name of the external location.
* @deprecated Use {@link #getExternalLocations(Namespace, String)}
* @return first matching external location
* @deprecated Use {@link #getExternalLocations(Namespace, String)} or
* {@link #getUniqueExternalLocation(Namespace, String)} since duplicate names may exist
*/
@Deprecated
public ExternalLocation getExternalLocation(Namespace namespace, String label);
@ -156,25 +165,27 @@ public interface ExternalManager {
/**
* Adds a new external library name
* @param name the new library name to add.
* @param libraryName the new external library name to add.
* @param source the source of this external library
* @return library
* @throws InvalidInputException
* @throws DuplicateNameException if another non-Library namespace has the same name
*/
public Library addExternalLibraryName(String name, SourceType source)
throws DuplicateNameException, InvalidInputException;
public Library addExternalLibraryName(String libraryName, SourceType source)
throws InvalidInputException, DuplicateNameException;
/**
* Get or create an external location associated with an library/file named extName
* and the label within that file specified by extLabel
* @param extName the external name
* @param libraryName the external library name
* @param extLabel the external label
* @param extAddr the external address
* @param sourceType the source type of this external library's symbol
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException
* @throws DuplicateNameException if another non-Library namespace has the same name
*/
public ExternalLocation addExtLocation(String extName, String extLabel, Address extAddr,
public ExternalLocation addExtLocation(String libraryName, String extLabel, Address extAddr,
SourceType sourceType) throws InvalidInputException, DuplicateNameException;
/**
@ -185,10 +196,9 @@ public interface ExternalManager {
* @param sourceType the source type of this external library's symbol
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException
*/
public ExternalLocation addExtLocation(Namespace extNamespace, String extLabel, Address extAddr,
SourceType sourceType) throws InvalidInputException, DuplicateNameException;
SourceType sourceType) throws InvalidInputException;
/**
* Get or create an external location in the indicated parent namespace with the specified name.
@ -200,25 +210,24 @@ public interface ExternalManager {
* location instead of creating a new one.
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException
*/
public ExternalLocation addExtLocation(Namespace extNamespace, String extLabel, Address extAddr,
SourceType sourceType, boolean reuseExisting)
throws InvalidInputException, DuplicateNameException;
throws InvalidInputException;
/**
* Get or create an external location associated with an library/file named extName
* and the label within that file specified by extLabel
* @param extName the external name
* @param libraryName the external library name
* @param extLabel the external label
* @param extAddr the external address
* @param sourceType the source type of this external library's symbol
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException
* @throws DuplicateNameException if another non-Library namespace has the same name
*/
public ExternalLocation addExtFunction(String extName, String extLabel, Address extAddr,
SourceType sourceType) throws DuplicateNameException, InvalidInputException;
public ExternalLocation addExtFunction(String libraryName, String extLabel, Address extAddr,
SourceType sourceType) throws InvalidInputException, DuplicateNameException;
/**
* Get or create an external function location associated with an library/file named extName
@ -229,10 +238,9 @@ public interface ExternalManager {
* @param sourceType the source type of this external library's symbol
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException if another non-Library namespace has the same name
*/
public ExternalLocation addExtFunction(Namespace extNamespace, String extLabel, Address extAddr,
SourceType sourceType) throws InvalidInputException, DuplicateNameException;
SourceType sourceType) throws InvalidInputException;
/**
* Get or create an external function location associated with an library/file named extName
@ -245,10 +253,9 @@ public interface ExternalManager {
* address is not null and not used in an existing location.
* @return external location
* @throws InvalidInputException
* @throws DuplicateNameException if another non-Library namespace has the same name
*/
public ExternalLocation addExtFunction(Namespace extNamespace, String extLabel, Address extAddr,
SourceType sourceType, boolean reuseExisting)
throws InvalidInputException, DuplicateNameException;
throws InvalidInputException;
}

View file

@ -173,6 +173,13 @@ public interface ReferenceManager {
*/
public void removeAllReferencesFrom(Address fromAddr);
/**
* Remove all stack, external, and memory references for the given
* to address.
* @param toAddr the address for which all references to should be removed.
*/
public void removeAllReferencesTo(Address toAddr);
/**
* Returns all references to the given variable. Only data references to storage
* are considered.

View file

@ -183,7 +183,8 @@ public interface Symbol {
throws DuplicateNameException, InvalidInputException, CircularDependencyException;
/**
* Delete the symbol and its associated resources.
* Delete the symbol and its associated resources. Any references symbol associations
* will be discarded.
* @return true if successful
*/
public boolean delete();

View file

@ -89,6 +89,11 @@ public class ReferenceManagerTestDouble implements ReferenceManager {
throw new UnsupportedOperationException();
}
@Override
public void removeAllReferencesTo(Address toAddr) {
throw new UnsupportedOperationException();
}
@Override
public Reference[] getReferencesTo(Variable var) {
throw new UnsupportedOperationException();