mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GT-2922 corrected FunctionDefinition issue and related merge bug
This commit is contained in:
parent
eaf0514298
commit
802bb8429a
9 changed files with 272 additions and 423 deletions
|
@ -85,9 +85,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#isDynamicallySized()
|
||||
*/
|
||||
@Override
|
||||
public boolean isDynamicallySized() {
|
||||
return false;
|
||||
|
@ -142,9 +139,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getArguments()
|
||||
*/
|
||||
@Override
|
||||
public ParameterDefinition[] getArguments() {
|
||||
lock.acquire();
|
||||
|
@ -157,9 +151,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getReturnType()
|
||||
*/
|
||||
@Override
|
||||
public DataType getReturnType() {
|
||||
lock.acquire();
|
||||
|
@ -168,7 +159,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
long dtId = record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL);
|
||||
DataType dt = dataMgr.getDataType(dtId);
|
||||
if (dt == null) {
|
||||
dt = DataType.VOID;
|
||||
dt = DataType.DEFAULT;
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
@ -187,12 +178,16 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
|
||||
private void doReplaceWith(FunctionDefinition functionDefinition) {
|
||||
setArguments(functionDefinition.getArguments());
|
||||
setReturnType(functionDefinition.getReturnType());
|
||||
try {
|
||||
setReturnType(functionDefinition.getReturnType());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
setReturnType(DEFAULT);
|
||||
}
|
||||
setVarArgs(functionDefinition.hasVarArgs());
|
||||
setGenericCallingConvention(functionDefinition.getGenericCallingConvention());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getComment()
|
||||
*/
|
||||
@Override
|
||||
public String getComment() {
|
||||
lock.acquire();
|
||||
|
@ -216,49 +211,31 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getMnemonic(ghidra.program.model.data.Settings)
|
||||
*/
|
||||
@Override
|
||||
public String getMnemonic(Settings settings) {
|
||||
return getPrototypeString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getLength()
|
||||
*/
|
||||
@Override
|
||||
public int getLength() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getDescription()
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Function Signature Data Type";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getValue(ghidra.program.model.mem.MemBuffer, ghidra.program.model.lang.ProcessorContext, ghidra.program.model.data.Settings, int)
|
||||
*/
|
||||
@Override
|
||||
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getRepresentation(ghidra.program.model.mem.MemBuffer, ghidra.program.model.lang.ProcessorContext, ghidra.program.model.data.Settings, int)
|
||||
*/
|
||||
@Override
|
||||
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
||||
return getPrototypeString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setArguments(ghidra.program.model.listing.Variable[])
|
||||
*/
|
||||
@Override
|
||||
public void setArguments(ParameterDefinition[] args) {
|
||||
lock.acquire();
|
||||
|
@ -272,17 +249,15 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
parameters.clear();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
DataType resolvedDt = resolve(args[i].getDataType());
|
||||
DataType type =
|
||||
ParameterDefinitionImpl.checkDataType(args[i].getDataType(), dataMgr, false);
|
||||
DataType resolvedDt = resolve(type);
|
||||
paramAdapter.createRecord(dataMgr.getID(resolvedDt), key, i, args[i].getName(),
|
||||
args[i].getComment(), args[i].getLength());
|
||||
resolvedDt.addParent(this);
|
||||
}
|
||||
getParameters();
|
||||
it = parameters.iterator();
|
||||
while (it.hasNext()) {
|
||||
ParameterDefinitionDB param = it.next();
|
||||
param.getDataType().addParent(this);
|
||||
}
|
||||
funDefAdapter.updateRecord(record, true);
|
||||
funDefAdapter.updateRecord(record, true); // update last change time
|
||||
dataMgr.dataTypeChanged(this);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
@ -293,24 +268,22 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setReturnType(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void setReturnType(DataType type) {
|
||||
type = ParameterDefinitionImpl.checkDataType(type, dataMgr, true);
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
getReturnType().removeParent(this);
|
||||
if (type == null) {
|
||||
type = DataType.VOID;
|
||||
type = DataType.DEFAULT;
|
||||
}
|
||||
DataType resolvedDt = resolve(type);
|
||||
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL,
|
||||
dataMgr.getID(resolvedDt));
|
||||
funDefAdapter.updateRecord(record, true);
|
||||
dataMgr.dataTypeChanged(this);
|
||||
resolvedDt.addParent(this);
|
||||
dataMgr.dataTypeChanged(this);
|
||||
}
|
||||
catch (IOException e) {
|
||||
dataMgr.dbError(e);
|
||||
|
@ -320,9 +293,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setComment(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setComment(String comment) {
|
||||
lock.acquire();
|
||||
|
@ -340,9 +310,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#dataTypeDeleted(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeDeleted(DataType dt) {
|
||||
lock.acquire();
|
||||
|
@ -352,13 +319,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
for (int i = 0; i < n; i++) {
|
||||
ParameterDefinitionDB param = parameters.get(i);
|
||||
if (param.getDataType() == dt) {
|
||||
dt.removeParent(this);
|
||||
param.setDataType(DataType.DEFAULT);
|
||||
}
|
||||
}
|
||||
if (dt == getReturnType()) {
|
||||
dt.removeParent(this);
|
||||
setReturnType(DataType.VOID);
|
||||
setReturnType(DataType.DEFAULT);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
@ -366,9 +331,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#isEquivalent(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public boolean isEquivalent(DataType dt) {
|
||||
if (dt == this) {
|
||||
|
@ -416,46 +378,50 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#setCategoryPath(ghidra.program.model.data.CategoryPath)
|
||||
*/
|
||||
@Override
|
||||
protected void doSetCategoryPathRecord(long categoryID) throws IOException {
|
||||
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_CAT_ID_COL, categoryID);
|
||||
funDefAdapter.updateRecord(record, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#setName(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void doSetNameRecord(String name) throws IOException {
|
||||
record.setString(FunctionDefinitionDBAdapter.FUNCTION_DEF_NAME_COL, name);
|
||||
funDefAdapter.updateRecord(record, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#dataTypeReplaced(ghidra.program.model.data.DataType, ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
if (newDt == this) {
|
||||
// TODO: document why this is neccessary
|
||||
newDt = DataType.DEFAULT;
|
||||
}
|
||||
DataType retType = getReturnType();
|
||||
if (oldDt == retType) {
|
||||
setReturnType(newDt);
|
||||
try {
|
||||
setReturnType(newDt);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// oldDt replaced with incompatible type - treat as removal
|
||||
dataTypeDeleted(oldDt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
int n = parameters.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
ParameterDefinitionDB param = parameters.get(i);
|
||||
if (param.getDataType() == oldDt) {
|
||||
oldDt.removeParent(this);
|
||||
param.setDataType(newDt);
|
||||
newDt.addParent(this);
|
||||
try {
|
||||
param.setDataType(newDt);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// oldDt replaced with incompatible type - treat as removal
|
||||
dataTypeDeleted(oldDt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +433,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
@Override
|
||||
public void replaceArgument(int ordinal, String name, DataType dt, String comment,
|
||||
SourceType source) {
|
||||
//TODO:
|
||||
if (dt.getLength() <= 0) {
|
||||
throw new IllegalArgumentException("Fixed length data type expected");
|
||||
}
|
||||
|
@ -499,17 +464,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#dataTypeNameChanged(ghidra.program.model.data.DataType, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeNameChanged(DataType dt, String oldName) {
|
||||
// don't care
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#hasVarArgs()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasVarArgs() {
|
||||
lock.acquire();
|
||||
|
@ -526,9 +485,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setVarArgs(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setVarArgs(boolean hasVarArgs) {
|
||||
lock.acquire();
|
||||
|
@ -555,9 +511,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setGenericCallingConvention(ghidra.program.model.data.GenericCallingConvention)
|
||||
*/
|
||||
@Override
|
||||
public void setGenericCallingConvention(GenericCallingConvention genericCallingConvention) {
|
||||
lock.acquire();
|
||||
|
@ -587,9 +540,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getGenericCallingConvention()
|
||||
*/
|
||||
@Override
|
||||
public GenericCallingConvention getGenericCallingConvention() {
|
||||
lock.acquire();
|
||||
|
@ -609,17 +559,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getLastChangeTime()
|
||||
*/
|
||||
@Override
|
||||
public long getLastChangeTime() {
|
||||
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_LAST_CHANGE_TIME_COL);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getSourceSyncTime()
|
||||
*/
|
||||
@Override
|
||||
public long getLastChangeTimeInSourceArchive() {
|
||||
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_SOURCE_SYNC_TIME_COL);
|
||||
|
|
|
@ -64,7 +64,13 @@ final class ParameterDefinitionDB implements ParameterDefinition {
|
|||
|
||||
@Override
|
||||
public void setDataType(DataType type) {
|
||||
type = ParameterDefinitionImpl.checkDataType(type, dataMgr);
|
||||
type = ParameterDefinitionImpl.checkDataType(type, dataMgr, false);
|
||||
|
||||
getDataType().removeParent(parent);
|
||||
|
||||
type = dataMgr.resolve(type, null);
|
||||
type.addParent(parent);
|
||||
|
||||
record.setLongValue(FunctionParameterAdapter.PARAMETER_DT_ID_COL,
|
||||
dataMgr.getResolvedID(type));
|
||||
record.setIntValue(FunctionParameterAdapter.PARAMETER_DT_LENGTH_COL, type.getLength());
|
||||
|
@ -136,27 +142,6 @@ final class ParameterDefinitionDB implements ParameterDefinition {
|
|||
return record.getIntValue(FunctionParameterAdapter.PARAMETER_ORDINAL_COL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof ParameterDefinition)) {
|
||||
return false;
|
||||
}
|
||||
ParameterDefinition p = (ParameterDefinition) obj;
|
||||
if ((getOrdinal() == p.getOrdinal()) && (getName().equals(p.getName())) &&
|
||||
(getDataType().isEquivalent(p.getDataType()))) {
|
||||
String myCmt = getComment();
|
||||
String otherCmt = p.getComment();
|
||||
return (myCmt == null) ? (otherCmt == null) : (myCmt.equals(otherCmt));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalent(Variable otherVar) {
|
||||
if (otherVar == null) {
|
||||
|
|
|
@ -32,6 +32,7 @@ public interface FunctionDefinition extends DataType, FunctionSignature {
|
|||
/**
|
||||
* Set the return data type for this function
|
||||
* @param type the return datatype to be set.
|
||||
* @throws IllegalArgumentException if data type is not a fixed length type
|
||||
*/
|
||||
public void setReturnType(DataType type);
|
||||
|
||||
|
|
|
@ -25,15 +25,12 @@ import ghidra.program.model.listing.*;
|
|||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.util.UniversalID;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
/**
|
||||
* Definition of a function for things like function pointers.
|
||||
*/
|
||||
public class FunctionDefinitionDataType extends GenericDataType implements FunctionDefinition {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private DataType returnType = DataType.DEFAULT;
|
||||
private ParameterDefinition[] params;
|
||||
private String comment;
|
||||
|
@ -77,8 +74,8 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
public FunctionDefinitionDataType(CategoryPath path, String name, FunctionSignature sig,
|
||||
UniversalID universalID, SourceArchive sourceArchive, long lastChangeTime,
|
||||
long lastChangeTimeInSourceArchive, DataTypeManager dtm) {
|
||||
super(path, name, universalID, sourceArchive, lastChangeTime,
|
||||
lastChangeTimeInSourceArchive, dtm);
|
||||
super(path, name, universalID, sourceArchive, lastChangeTime, lastChangeTimeInSourceArchive,
|
||||
dtm);
|
||||
init(sig);
|
||||
}
|
||||
|
||||
|
@ -135,82 +132,40 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sig
|
||||
*/
|
||||
private void copySignature(FunctionSignature sig) {
|
||||
comment = sig.getComment();
|
||||
DataType rtnType = sig.getReturnType();
|
||||
if (rtnType == null) {
|
||||
rtnType = DataType.DEFAULT;
|
||||
}
|
||||
setReturnType(rtnType.clone(getDataTypeManager()));
|
||||
setArguments(sig.getArguments());
|
||||
hasVarArgs = sig.hasVarArgs();
|
||||
genericCallingConvention = sig.getGenericCallingConvention();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setArguments(ghidra.program.model.listing.ParameterDefinition[])
|
||||
*/
|
||||
@Override
|
||||
public void setArguments(ParameterDefinition[] args) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i].getDataType().removeParent(this);
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
if (args[0].getDataType() instanceof VoidDataType) {
|
||||
args = new ParameterDefinition[0];
|
||||
}
|
||||
}
|
||||
|
||||
params = new ParameterDefinition[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
DataType dt = args[i].getDataType();
|
||||
dt.addParent(this);
|
||||
params[i] =
|
||||
new ParameterDefinitionImpl(args[i].getName(), dt.clone(getDataTypeManager()),
|
||||
args[i].getComment(), i);
|
||||
params[i] = new ParameterDefinitionImpl(args[i].getName(),
|
||||
dt.clone(getDataTypeManager()), args[i].getComment(), i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.data.DataType#isDynamicallySized()
|
||||
*/
|
||||
@Override
|
||||
public boolean isDynamicallySized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setReturnType(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void setReturnType(DataType type) {
|
||||
if (type == null || type.getLength() < 0) {
|
||||
returnType = DataType.DEFAULT;
|
||||
}
|
||||
else {
|
||||
returnType.removeParent(this);
|
||||
}
|
||||
returnType = type;
|
||||
if (returnType != null) {
|
||||
returnType.addParent(this);
|
||||
}
|
||||
returnType = ParameterDefinitionImpl.checkDataType(type, dataMgr, true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setComment(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.FunctionDefinition#setVarArgs(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void setVarArgs(boolean hasVarArgs) {
|
||||
this.hasVarArgs = hasVarArgs;
|
||||
|
@ -241,41 +196,26 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getMnemonic(ghidra.program.model.data.Settings)
|
||||
*/
|
||||
@Override
|
||||
public String getMnemonic(Settings settings) {
|
||||
return getPrototypeString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getLength()
|
||||
*/
|
||||
@Override
|
||||
public int getLength() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getDescription()
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Function: " + getMnemonic(null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getValue(ghidra.program.model.mem.MemBuffer, ghidra.program.model.lang.ProcessorContext, ghidra.program.model.data.Settings, int)
|
||||
*/
|
||||
@Override
|
||||
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#getRepresentation(ghidra.program.model.mem.MemBuffer, ghidra.program.model.lang.ProcessorContext, ghidra.program.model.data.Settings, int)
|
||||
*/
|
||||
@Override
|
||||
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
||||
|
||||
|
@ -320,9 +260,6 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getArguments()
|
||||
*/
|
||||
@Override
|
||||
public ParameterDefinition[] getArguments() {
|
||||
ParameterDefinition[] args = new ParameterDefinition[params.length];
|
||||
|
@ -330,25 +267,16 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
return args;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getReturnType()
|
||||
*/
|
||||
@Override
|
||||
public DataType getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#getComment()
|
||||
*/
|
||||
@Override
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.listing.FunctionSignature#hasVarArgs()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasVarArgs() {
|
||||
return hasVarArgs;
|
||||
|
@ -405,30 +333,37 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#dataTypeReplaced(ghidra.program.model.data.DataType, ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
||||
if (returnType == oldDt) {
|
||||
oldDt.removeParent(this);
|
||||
returnType = newDt;
|
||||
newDt.addParent(this);
|
||||
|
||||
if (newDt == this) {
|
||||
// TODO: document why this is neccessary
|
||||
newDt = DataType.DEFAULT;
|
||||
}
|
||||
DataType retType = getReturnType();
|
||||
if (oldDt == retType) {
|
||||
try {
|
||||
setReturnType(newDt);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// oldDt replaced with incompatible type - treat as removal
|
||||
dataTypeDeleted(oldDt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
ParameterDefinition param = params[i];
|
||||
if (param.getDataType() == oldDt) {
|
||||
oldDt.removeParent(this);
|
||||
try {
|
||||
param.setDataType(newDt);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
catch (IllegalArgumentException e) {
|
||||
// oldDt replaced with incompatible type - treat as removal
|
||||
dataTypeDeleted(oldDt);
|
||||
return;
|
||||
}
|
||||
newDt.addParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -439,57 +374,36 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
ParameterDefinition[] newParams = new ParameterDefinition[ordinal + 1];
|
||||
System.arraycopy(params, 0, newParams, 0, params.length);
|
||||
for (int i = params.length; i < ordinal + 1; i++) {
|
||||
newParams[i] =
|
||||
new ParameterDefinitionImpl(Function.DEFAULT_PARAM_PREFIX + (i + 1),
|
||||
DataType.DEFAULT, newComment, i);
|
||||
newParams[i] = new ParameterDefinitionImpl(Function.DEFAULT_PARAM_PREFIX + (i + 1),
|
||||
DataType.DEFAULT, newComment, i);
|
||||
}
|
||||
params = newParams;
|
||||
}
|
||||
params[ordinal].getDataType().removeParent(this);
|
||||
params[ordinal] = new ParameterDefinitionImpl(newName, dt, newComment, ordinal);
|
||||
dt.addParent(this);
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#dataTypeSizeChanged(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeSizeChanged(DataType dt) {
|
||||
// ignore - no affect
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#dataTypeDeleted(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeDeleted(DataType dt) {
|
||||
if (returnType == dt) {
|
||||
dt.removeParent(this);
|
||||
returnType = new VoidDataType();
|
||||
returnType = DataType.DEFAULT;
|
||||
}
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].getDataType() == dt) {
|
||||
try {
|
||||
params[i].setDataType(DataType.DEFAULT);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
throw new AssertException(
|
||||
"Setting DataType to Default should not throw this exception");
|
||||
}
|
||||
params[i].setDataType(DataType.DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#dataTypeNameChanged(ghidra.program.model.data.DataType, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void dataTypeNameChanged(DataType dt, String oldName) {
|
||||
// ignore - no affect
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.program.model.data.DataType#dependsOn(ghidra.program.model.data.DataType)
|
||||
*/
|
||||
@Override
|
||||
public boolean dependsOn(DataType dt) {
|
||||
return false;
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package ghidra.program.model.data;
|
||||
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.program.model.listing.Variable;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
/**
|
||||
* <code>ParameterDefinition</code> specifies a parameter which can be
|
||||
|
@ -25,7 +25,9 @@ import ghidra.util.exception.InvalidInputException;
|
|||
public interface ParameterDefinition extends Comparable<ParameterDefinition> {
|
||||
|
||||
/**
|
||||
* Returns the ordinal (index) of this parameter within the function signature.
|
||||
* Get the parameter ordinal
|
||||
*
|
||||
* @return the ordinal (index) of this parameter within the function signature.
|
||||
*/
|
||||
int getOrdinal();
|
||||
|
||||
|
@ -39,9 +41,9 @@ public interface ParameterDefinition extends Comparable<ParameterDefinition> {
|
|||
/**
|
||||
* Set the Data Type of this variable. The given dataType must have a fixed length.
|
||||
* @param type the data type
|
||||
* @throws InvalidInputException if data type is not a fixed length or will not fit.
|
||||
* @throws IllegalArgumentException if data type is not a fixed length type
|
||||
*/
|
||||
public void setDataType(DataType type) throws InvalidInputException;
|
||||
public void setDataType(DataType type);
|
||||
|
||||
/**
|
||||
* Get the Name of this variable.
|
||||
|
@ -77,16 +79,22 @@ public interface ParameterDefinition extends Comparable<ParameterDefinition> {
|
|||
public void setComment(String comment);
|
||||
|
||||
/**
|
||||
* Returns true if the specified variable
|
||||
* represents the same parameter by ordinal
|
||||
* and dataType
|
||||
* Determine if a variable corresponds to a parameter which is equivelent to
|
||||
* this parameter definition by both ordinal and datatype. Name is not considered
|
||||
* relavent.
|
||||
* @param variable variable to be compared with this parameter definition.
|
||||
* @return true if the specified variable represents the same parameter by ordinal
|
||||
* and dataType. False will always be returned if specified variable is
|
||||
* not a {@link Parameter}.
|
||||
*/
|
||||
public boolean isEquivalent(Variable variable);
|
||||
|
||||
/**
|
||||
* Returns true if the specified parameter definition
|
||||
* represents the same parameter by ordinal
|
||||
* and dataType
|
||||
* Determine if parm is equivelent to this parameter definition by both ordinal
|
||||
* and datatype. Name is not considered relavent.
|
||||
* @param parm parameter definition to be compared with this parameter definition.
|
||||
* @return true if the specified parameter definition represents the same parameter
|
||||
* by ordinal and dataType.
|
||||
*/
|
||||
public boolean isEquivalent(ParameterDefinition parm);
|
||||
}
|
||||
|
|
|
@ -15,13 +15,10 @@
|
|||
*/
|
||||
package ghidra.program.model.data;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.program.model.listing.Variable;
|
||||
import ghidra.program.model.symbol.SymbolUtilities;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class ParameterDefinitionImpl implements ParameterDefinition {
|
||||
|
||||
|
@ -49,13 +46,15 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
|||
* @param ordinal the index of this parameter within the function signature.
|
||||
*/
|
||||
protected ParameterDefinitionImpl(String name, DataType dataType, String comment, int ordinal) {
|
||||
this.dataType = checkDataType(dataType, null);
|
||||
this.dataType = checkDataType(dataType, null, false);
|
||||
this.name = name;
|
||||
this.comment = comment;
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
public static DataType checkDataType(DataType dataType, DataTypeManager dtMgr) {
|
||||
public static DataType checkDataType(DataType dataType, DataTypeManager dtMgr, boolean isReturn)
|
||||
throws IllegalArgumentException {
|
||||
String kind = isReturn ? "Return" : "Parameter";
|
||||
if (dataType == null) {
|
||||
dataType = DataType.DEFAULT;
|
||||
}
|
||||
|
@ -65,21 +64,23 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
|||
}
|
||||
else if (dataType instanceof Dynamic || dataType instanceof FactoryDataType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter may not be defined with Dynamic or Factory data-type: " +
|
||||
kind + " type may not be defined with Dynamic or Factory data-type: " +
|
||||
dataType.getName());
|
||||
}
|
||||
dataType = dataType.clone(dtMgr != null ? dtMgr : dataType.getDataTypeManager());
|
||||
if (!dataType.isDynamicallySized() && dataType.getLength() < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter must be specified with fixed-length data type: " + dataType.getName());
|
||||
throw new IllegalArgumentException(kind +
|
||||
" type must be specified with fixed-length data type: " + dataType.getName());
|
||||
}
|
||||
if (dataType instanceof VoidDataType) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter may not specify the void datatype - empty parameter list should be used");
|
||||
if (!isReturn) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter type may not specify the void datatype - empty parameter list should be used");
|
||||
}
|
||||
}
|
||||
if (!(dataType instanceof Composite) && dataType.getLength() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter must be specified with fixed-length data type: " + dataType.getName());
|
||||
else if (!(dataType instanceof Composite) && dataType.getLength() == 0) {
|
||||
throw new IllegalArgumentException(kind +
|
||||
" type must be specified with fixed-length data type: " + dataType.getName());
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
@ -129,8 +130,8 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDataType(DataType type) throws InvalidInputException {
|
||||
this.dataType = checkDataType(type, dataType.getDataTypeManager());
|
||||
public void setDataType(DataType type) {
|
||||
this.dataType = checkDataType(type, dataType.getDataTypeManager(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -141,31 +142,6 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof ParameterDefinition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ParameterDefinition otherVar = (ParameterDefinition) obj;
|
||||
if (ordinal != otherVar.getOrdinal()) {
|
||||
return false;
|
||||
}
|
||||
if (!DataTypeUtilities.isSameOrEquivalentDataType(dataType, otherVar.getDataType())) {
|
||||
return false;
|
||||
}
|
||||
if (!StringUtils.equals(getName(), otherVar.getName())) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.equals(getComment(), otherVar.getComment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalent(Variable variable) {
|
||||
if (variable == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue