mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge branch 'GP-1525_ghidra1_ExternalFunctionPrimary' into Ghidra_10.1
This commit is contained in:
commit
5c82f87905
18 changed files with 553 additions and 433 deletions
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue