mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-4078 added delayed pointer resolve logic to FunctionDefinitionDB
This commit is contained in:
parent
2e5b4fc22a
commit
3eb59b3418
6 changed files with 203 additions and 111 deletions
|
@ -213,12 +213,11 @@ abstract class CompositeDB extends DataTypeDB implements CompositeInternal {
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
record.setString(CompositeDBAdapter.COMPOSITE_COMMENT_COL, desc);
|
record.setString(CompositeDBAdapter.COMPOSITE_COMMENT_COL, desc);
|
||||||
try {
|
compositeAdapter.updateRecord(record, true);
|
||||||
compositeAdapter.updateRecord(record, true);
|
dataMgr.dataTypeChanged(this, false);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.release();
|
lock.release();
|
||||||
|
|
|
@ -1372,25 +1372,23 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
SourceArchive sourceArchive) throws DataTypeDependencyException {
|
SourceArchive sourceArchive) throws DataTypeDependencyException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (existingDataType instanceof StructureDB) {
|
if (existingDataType instanceof StructureDB existingStruct) {
|
||||||
if (!(dataType instanceof StructureInternal)) {
|
if (!(dataType instanceof StructureInternal replacementStruct)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
StructureDB existingStruct = (StructureDB) existingDataType;
|
existingStruct.doReplaceWith(replacementStruct, true);
|
||||||
existingStruct.doReplaceWith((StructureInternal) dataType, true);
|
|
||||||
}
|
}
|
||||||
else if (existingDataType instanceof UnionDB) {
|
else if (existingDataType instanceof UnionDB existingUnion) {
|
||||||
if (!(dataType instanceof UnionInternal)) {
|
if (!(dataType instanceof UnionInternal replacementUnion)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
UnionDB existingUnion = (UnionDB) existingDataType;
|
existingUnion.doReplaceWith(replacementUnion, true);
|
||||||
existingUnion.doReplaceWith((UnionInternal) dataType, true);
|
|
||||||
}
|
}
|
||||||
else if (existingDataType instanceof FunctionDefinitionDB) {
|
else if (existingDataType instanceof FunctionDefinitionDB existingFuncDef) {
|
||||||
if (!(dataType instanceof FunctionDefinition)) {
|
if (!(dataType instanceof FunctionDefinition replacementFuncDef)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
existingDataType.replaceWith(dataType);
|
existingFuncDef.doReplaceWith(replacementFuncDef, true);
|
||||||
}
|
}
|
||||||
else if (existingDataType instanceof EnumDB) {
|
else if (existingDataType instanceof EnumDB) {
|
||||||
if (!(dataType instanceof Enum)) {
|
if (!(dataType instanceof Enum)) {
|
||||||
|
@ -3015,7 +3013,6 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
category.dataTypeAdded(structDB);
|
category.dataTypeAdded(structDB);
|
||||||
|
|
||||||
structDB.doReplaceWith(struct, false);
|
structDB.doReplaceWith(struct, false);
|
||||||
structDB.setDescription(struct.getDescription());
|
|
||||||
|
|
||||||
// doReplaceWith may have updated the last change time so set it back to what we want.
|
// doReplaceWith may have updated the last change time so set it back to what we want.
|
||||||
structDB.setLastChangeTime(struct.getLastChangeTime());
|
structDB.setLastChangeTime(struct.getLastChangeTime());
|
||||||
|
@ -3079,7 +3076,6 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
category.dataTypeAdded(unionDB);
|
category.dataTypeAdded(unionDB);
|
||||||
|
|
||||||
unionDB.doReplaceWith(union, false);
|
unionDB.doReplaceWith(union, false);
|
||||||
unionDB.setDescription(union.getDescription());
|
|
||||||
|
|
||||||
// doReplaceWith updated the last change time so set it back to what we want.
|
// doReplaceWith updated the last change time so set it back to what we want.
|
||||||
unionDB.setLastChangeTime(union.getLastChangeTime());
|
unionDB.setLastChangeTime(union.getLastChangeTime());
|
||||||
|
@ -3326,8 +3322,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
// Make sure category knows about function definition before args/return resolved
|
// Make sure category knows about function definition before args/return resolved
|
||||||
cat.dataTypeAdded(funDefDb);
|
cat.dataTypeAdded(funDefDb);
|
||||||
|
|
||||||
funDefDb.setArguments(funDef.getArguments());
|
funDefDb.doReplaceWith(funDef, false);
|
||||||
funDefDb.setReturnType(funDef.getReturnType());
|
|
||||||
|
|
||||||
// setArguments updated the last change time so set it back to what we want.
|
// setArguments updated the last change time so set it back to what we want.
|
||||||
funDefDb.setLastChangeTime(funDef.getLastChangeTime());
|
funDefDb.setLastChangeTime(funDef.getLastChangeTime());
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
package ghidra.program.database.data;
|
package ghidra.program.database.data;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import db.DBRecord;
|
import db.DBRecord;
|
||||||
import db.Field;
|
import db.Field;
|
||||||
|
@ -153,10 +154,10 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParameterDefinition[] getArguments() {
|
public ParameterDefinitionDB[] getArguments() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
ParameterDefinition[] vars = new ParameterDefinition[parameters.size()];
|
ParameterDefinitionDB[] vars = new ParameterDefinitionDB[parameters.size()];
|
||||||
return parameters.toArray(vars);
|
return parameters.toArray(vars);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -183,41 +184,77 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replaceWith(DataType dataType) {
|
public void replaceWith(DataType dataType) {
|
||||||
if (!(dataType instanceof FunctionDefinition)) {
|
if (!(dataType instanceof FunctionDefinition functionDefinition)) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
doReplaceWith((FunctionDefinition) dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doReplaceWith(FunctionDefinition functionDefinition) {
|
|
||||||
|
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
boolean isResolveCacheOwner = dataMgr.activateResolveCache();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
setArguments(functionDefinition.getArguments());
|
doReplaceWith(functionDefinition, true);
|
||||||
try {
|
|
||||||
setReturnType(functionDefinition.getReturnType());
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e) {
|
|
||||||
setReturnType(DEFAULT);
|
|
||||||
}
|
|
||||||
setVarArgs(functionDefinition.hasVarArgs());
|
|
||||||
setNoReturn(functionDefinition.hasNoReturn());
|
|
||||||
try {
|
|
||||||
setCallingConvention(functionDefinition.getCallingConventionName(), false);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
// will not happen
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
if (isResolveCacheOwner) {
|
||||||
|
dataMgr.flushResolveQueue(true);
|
||||||
|
}
|
||||||
lock.release();
|
lock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void doReplaceWith(FunctionDefinition functionDefinition, boolean notify) throws IOException {
|
||||||
|
doSetArguments(functionDefinition.getArguments(), true, false);
|
||||||
|
try {
|
||||||
|
doSetReturnType(functionDefinition.getReturnType(), true, false);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
setReturnType(DEFAULT);
|
||||||
|
}
|
||||||
|
doSetVarArgs(functionDefinition.hasVarArgs(), false);
|
||||||
|
doSetNoReturn(functionDefinition.hasNoReturn(), false);
|
||||||
|
try {
|
||||||
|
doSetCallingConvention(functionDefinition.getCallingConventionName(), false, false);
|
||||||
|
}
|
||||||
|
catch (InvalidInputException e) {
|
||||||
|
// will not happen
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setString(FunctionDefinitionDBAdapter.FUNCTION_DEF_COMMENT_COL,
|
||||||
|
functionDefinition.getComment());
|
||||||
|
funDefAdapter.updateRecord(record, false);
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointerPostResolveRequired) {
|
||||||
|
dataMgr.queuePostResolve(this, functionDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postPointerResolve(DataType definitionDt, DataTypeConflictHandler handler) {
|
||||||
|
FunctionDefinition funcDef = (FunctionDefinition) definitionDt;
|
||||||
|
ParameterDefinition[] definedArguments = funcDef.getArguments();
|
||||||
|
ParameterDefinitionDB[] myArguments = getArguments();
|
||||||
|
if (definedArguments.length != myArguments.length) {
|
||||||
|
throw new IllegalArgumentException("mismatched definition datatype");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < definedArguments.length; i++) {
|
||||||
|
ParameterDefinition arg = definedArguments[i];
|
||||||
|
DataType dt = arg.getDataType();
|
||||||
|
if (dt instanceof Pointer) {
|
||||||
|
myArguments[i].doSetDataType(dt, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType dt = funcDef.getReturnType();
|
||||||
|
if (dt instanceof Pointer) {
|
||||||
|
doSetReturnType(dt, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getComment() {
|
public String getComment() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -274,29 +311,20 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
return getPrototypeString();
|
return getPrototypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DataType doCheckedResolve(DataType dt) {
|
||||||
|
if (dt instanceof Pointer) {
|
||||||
|
pointerPostResolveRequired = true;
|
||||||
|
return resolve(((Pointer) dt).newPointer(DataType.DEFAULT));
|
||||||
|
}
|
||||||
|
return resolve(dt);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setArguments(ParameterDefinition[] args) {
|
public void setArguments(ParameterDefinition[] args) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
Iterator<ParameterDefinitionDB> it = parameters.iterator();
|
doSetArguments(args, false, true);
|
||||||
while (it.hasNext()) {
|
|
||||||
ParameterDefinitionDB param = it.next();
|
|
||||||
param.getDataType().removeParent(this);
|
|
||||||
paramAdapter.removeRecord(param.getKey());
|
|
||||||
}
|
|
||||||
parameters.clear();
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
DataType type =
|
|
||||||
ParameterDefinitionImpl.validateDataType(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);
|
|
||||||
}
|
|
||||||
loadParameters();
|
|
||||||
funDefAdapter.updateRecord(record, true); // update last change time
|
|
||||||
dataMgr.dataTypeChanged(this, false);
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
|
@ -306,29 +334,60 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doSetArguments(ParameterDefinition[] args, boolean checkedResolveReqd,
|
||||||
|
boolean notify) throws IOException {
|
||||||
|
|
||||||
|
for (ParameterDefinitionDB param : parameters) {
|
||||||
|
param.getDataType().removeParent(this);
|
||||||
|
paramAdapter.removeRecord(param.getKey());
|
||||||
|
}
|
||||||
|
parameters.clear();
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
DataType type =
|
||||||
|
ParameterDefinitionImpl.validateDataType(args[i].getDataType(), dataMgr, false);
|
||||||
|
DataType resolvedDt = checkedResolveReqd ? doCheckedResolve(type) : resolve(type);
|
||||||
|
paramAdapter.createRecord(dataMgr.getID(resolvedDt), key, i, args[i].getName(),
|
||||||
|
args[i].getComment(), args[i].getLength());
|
||||||
|
resolvedDt.addParent(this);
|
||||||
|
}
|
||||||
|
loadParameters();
|
||||||
|
funDefAdapter.updateRecord(record, true); // update last change time
|
||||||
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReturnType(DataType type) {
|
public void setReturnType(DataType type) {
|
||||||
type = ParameterDefinitionImpl.validateDataType(type, dataMgr, true);
|
type = ParameterDefinitionImpl.validateDataType(type, dataMgr, true);
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
|
doSetReturnType(type, false, true);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
lock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doSetReturnType(DataType type, boolean checkedResolveReqd, boolean notify) {
|
||||||
|
try {
|
||||||
getReturnType().removeParent(this);
|
getReturnType().removeParent(this);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
type = DataType.DEFAULT;
|
type = DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
DataType resolvedDt = resolve(type);
|
DataType resolvedDt = checkedResolveReqd ? doCheckedResolve(type) : resolve(type);
|
||||||
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL,
|
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL,
|
||||||
dataMgr.getID(resolvedDt));
|
dataMgr.getID(resolvedDt));
|
||||||
funDefAdapter.updateRecord(record, true);
|
funDefAdapter.updateRecord(record, true);
|
||||||
resolvedDt.addParent(this);
|
resolvedDt.addParent(this);
|
||||||
dataMgr.dataTypeChanged(this, false);
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
lock.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -558,59 +617,79 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
byte flags = record.getByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL);
|
doSetVarArgs(hasVarArgs, true);
|
||||||
if (hasVarArgs) {
|
}
|
||||||
flags |= FunctionDefinitionDBAdapter.FUNCTION_DEF_VARARG_FLAG;
|
catch (IOException e) {
|
||||||
}
|
dataMgr.dbError(e);
|
||||||
else {
|
|
||||||
flags &= ~FunctionDefinitionDBAdapter.FUNCTION_DEF_VARARG_FLAG;
|
|
||||||
}
|
|
||||||
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL, flags);
|
|
||||||
try {
|
|
||||||
funDefAdapter.updateRecord(record, true);
|
|
||||||
dataMgr.dataTypeChanged(this, false);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
dataMgr.dbError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.release();
|
lock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doSetVarArgs(boolean hasVarArgs, boolean notify) throws IOException {
|
||||||
|
|
||||||
|
if (hasVarArgs == hasVarArgs()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte flags = record.getByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL);
|
||||||
|
if (hasVarArgs) {
|
||||||
|
flags |= FunctionDefinitionDBAdapter.FUNCTION_DEF_VARARG_FLAG;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flags &= ~FunctionDefinitionDBAdapter.FUNCTION_DEF_VARARG_FLAG;
|
||||||
|
}
|
||||||
|
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL, flags);
|
||||||
|
funDefAdapter.updateRecord(record, true);
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNoReturn(boolean hasNoReturn) {
|
public void setNoReturn(boolean hasNoReturn) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
byte flags = record.getByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL);
|
doSetNoReturn(hasNoReturn, true);
|
||||||
if (hasNoReturn) {
|
}
|
||||||
flags |= FunctionDefinitionDBAdapter.FUNCTION_DEF_NORETURN_FLAG;
|
catch (IOException e) {
|
||||||
}
|
dataMgr.dbError(e);
|
||||||
else {
|
|
||||||
flags &= ~FunctionDefinitionDBAdapter.FUNCTION_DEF_NORETURN_FLAG;
|
|
||||||
}
|
|
||||||
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL, flags);
|
|
||||||
try {
|
|
||||||
funDefAdapter.updateRecord(record, true);
|
|
||||||
dataMgr.dataTypeChanged(this, false);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
dataMgr.dbError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.release();
|
lock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doSetNoReturn(boolean hasNoReturn, boolean notify) throws IOException {
|
||||||
|
|
||||||
|
if (hasNoReturn == hasNoReturn()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte flags = record.getByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL);
|
||||||
|
if (hasNoReturn) {
|
||||||
|
flags |= FunctionDefinitionDBAdapter.FUNCTION_DEF_NORETURN_FLAG;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flags &= ~FunctionDefinitionDBAdapter.FUNCTION_DEF_NORETURN_FLAG;
|
||||||
|
}
|
||||||
|
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_FLAGS_COL, flags);
|
||||||
|
funDefAdapter.updateRecord(record, true);
|
||||||
|
|
||||||
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setGenericCallingConvention(GenericCallingConvention genericCallingConvention) {
|
public void setGenericCallingConvention(GenericCallingConvention genericCallingConvention) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
setCallingConvention(genericCallingConvention.name(), false);
|
doSetCallingConvention(genericCallingConvention.name(), false, true);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
|
@ -628,7 +707,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
setCallingConvention(conventionName, true);
|
doSetCallingConvention(conventionName, true, true);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
|
@ -638,12 +717,14 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCallingConvention(String conventionName, boolean restrictive)
|
private void doSetCallingConvention(String conventionName, boolean restrictive, boolean notify)
|
||||||
throws InvalidInputException, IOException {
|
throws InvalidInputException, IOException {
|
||||||
byte id = dataMgr.getCallingConventionID(conventionName, restrictive);
|
byte id = dataMgr.getCallingConventionID(conventionName, restrictive);
|
||||||
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_CALLCONV_COL, id);
|
record.setByteValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_CALLCONV_COL, id);
|
||||||
funDefAdapter.updateRecord(record, true);
|
funDefAdapter.updateRecord(record, true);
|
||||||
dataMgr.dataTypeChanged(this, false);
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(this, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -61,19 +61,32 @@ final class ParameterDefinitionDB implements ParameterDefinition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDataType(DataType type) {
|
public void setDataType(DataType type) {
|
||||||
type = ParameterDefinitionImpl.validateDataType(type, dataMgr, false);
|
// TODO: This is not a DatabaseObject so it lacks ability to refresh properly
|
||||||
|
// and parameter objects are not singletons. It also lacks locking.
|
||||||
|
// There is risk of using a stale or deleted parameter object which could lead
|
||||||
|
// to corruption of a function definition and datatype parent tracking.
|
||||||
|
|
||||||
getDataType().removeParent(parent);
|
doSetDataType(type, true);
|
||||||
|
}
|
||||||
|
|
||||||
type = dataMgr.resolve(type, null);
|
void doSetDataType(DataType type, boolean notify) {
|
||||||
type.addParent(parent);
|
|
||||||
|
|
||||||
record.setLongValue(FunctionParameterAdapter.PARAMETER_DT_ID_COL,
|
|
||||||
dataMgr.getResolvedID(type));
|
|
||||||
record.setIntValue(FunctionParameterAdapter.PARAMETER_DT_LENGTH_COL, type.getLength());
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
type = ParameterDefinitionImpl.validateDataType(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());
|
||||||
adapter.updateRecord(record);
|
adapter.updateRecord(record);
|
||||||
dataMgr.dataTypeChanged(parent, false);
|
|
||||||
|
if (notify) {
|
||||||
|
dataMgr.dataTypeChanged(parent, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(e);
|
dataMgr.dbError(e);
|
||||||
|
|
|
@ -1645,6 +1645,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_NUM_COMPONENTS_COL, numComponents);
|
record.setIntValue(CompositeDBAdapter.COMPOSITE_NUM_COMPONENTS_COL, numComponents);
|
||||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_LENGTH_COL, structLength);
|
record.setIntValue(CompositeDBAdapter.COMPOSITE_LENGTH_COL, structLength);
|
||||||
record.setIntValue(CompositeDBAdapter.COMPOSITE_ALIGNMENT_COL, structAlignment);
|
record.setIntValue(CompositeDBAdapter.COMPOSITE_ALIGNMENT_COL, structAlignment);
|
||||||
|
record.setString(CompositeDBAdapter.COMPOSITE_COMMENT_COL, struct.getDescription());
|
||||||
compositeAdapter.updateRecord(record, true); // updates timestamp
|
compositeAdapter.updateRecord(record, true); // updates timestamp
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
|
|
|
@ -344,6 +344,9 @@ class UnionDB extends CompositeDB implements UnionInternal {
|
||||||
doAdd(resolvedDts[i], dtc.getLength(), dtc.getFieldName(), dtc.getComment(), false);
|
doAdd(resolvedDts[i], dtc.getLength(), dtc.getFieldName(), dtc.getComment(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record.setString(CompositeDBAdapter.COMPOSITE_COMMENT_COL, union.getDescription());
|
||||||
|
compositeAdapter.updateRecord(record, false);
|
||||||
|
|
||||||
repack(false, false); // updates timestamp
|
repack(false, false); // updates timestamp
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue