mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +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
|
@ -36,7 +36,6 @@ import ghidra.util.*;
|
||||||
import ghidra.util.datastruct.LongObjectHashtable;
|
import ghidra.util.datastruct.LongObjectHashtable;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for merging category and data type changes
|
* Manager for merging category and data type changes
|
||||||
|
@ -93,11 +92,12 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for merging the data types using the four programs.
|
* Manager for merging the data types using the four programs.
|
||||||
* @param resultPgm the program to be updated with the result of the merge.
|
* @param mergeManager overall merge manager for domain object
|
||||||
|
* @param resultDomainObject the program to be updated with the result of the merge.
|
||||||
* This is the program that will actually get checked in.
|
* This is the program that will actually get checked in.
|
||||||
* @param myPgm the program requesting to be checked in.
|
* @param myDomainObject the program requesting to be checked in.
|
||||||
* @param originalPgm the program that was checked out.
|
* @param originalDomainObject the program that was checked out.
|
||||||
* @param latestPgm the latest checked-in version of the program.
|
* @param latestDomainObject the latest checked-in version of the program.
|
||||||
* @param latestChanges the address set of changes between original and latest versioned program.
|
* @param latestChanges the address set of changes between original and latest versioned program.
|
||||||
* @param myChanges the address set of changes between original and my modified program.
|
* @param myChanges the address set of changes between original and my modified program.
|
||||||
*/
|
*/
|
||||||
|
@ -185,8 +185,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge the data types using the four programs.
|
* Merge the data types using the four programs.
|
||||||
* @param monitor
|
* @param monitor merge task monitor
|
||||||
* @return true if the merge completed
|
|
||||||
* @see MergeConstants
|
* @see MergeConstants
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -262,7 +261,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For JUnit testing only, set the option for resolving a conflict.
|
* For JUnit testing only, set the option for resolving a conflict.
|
||||||
* @param option
|
* @param option forced conflict resolution option
|
||||||
*/
|
*/
|
||||||
void setConflictResolution(int option) {
|
void setConflictResolution(int option) {
|
||||||
conflictOption = option;
|
conflictOption = option;
|
||||||
|
@ -272,9 +271,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
private void processSourceArchiveChanges() throws CancelledException {
|
private void processSourceArchiveChanges() throws CancelledException {
|
||||||
conflictOption = OPTION_MY;
|
conflictOption = OPTION_MY;
|
||||||
for (int i = 0; i < myArchiveChangeList.size(); i++) {
|
for (int i = 0; i < myArchiveChangeList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = myArchiveChangeList.get(i).longValue();
|
long id = myArchiveChangeList.get(i).longValue();
|
||||||
|
@ -324,9 +321,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
private void processSourceArchiveAdditions() throws CancelledException {
|
private void processSourceArchiveAdditions() throws CancelledException {
|
||||||
for (int i = 0; i < myArchiveAddedList.size(); i++) {
|
for (int i = 0; i < myArchiveAddedList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = myArchiveAddedList.get(i).longValue();
|
long id = myArchiveAddedList.get(i).longValue();
|
||||||
|
@ -389,9 +384,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
private void processSourceArchiveConflicts() throws CancelledException {
|
private void processSourceArchiveConflicts() throws CancelledException {
|
||||||
|
|
||||||
for (int i = 0; i < archiveConflictList.size(); i++) {
|
for (int i = 0; i < archiveConflictList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long sourceArchiveID = archiveConflictList.get(i).longValue();
|
long sourceArchiveID = archiveConflictList.get(i).longValue();
|
||||||
|
@ -418,13 +411,11 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new categories.
|
* Add new categories.
|
||||||
* @throws CancelledException
|
* @throws CancelledException if task cancelled
|
||||||
*/
|
*/
|
||||||
private void processCategoriesAdded() throws CancelledException {
|
private void processCategoriesAdded() throws CancelledException {
|
||||||
for (int i = 0; i < myCatAddedList.size(); i++) {
|
for (int i = 0; i < myCatAddedList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = myCatAddedList.get(i).longValue();
|
long id = myCatAddedList.get(i).longValue();
|
||||||
|
@ -439,14 +430,12 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process conflicts for categories.
|
* Process conflicts for categories.
|
||||||
* @throws CancelledException
|
* @throws CancelledException task was cancelled
|
||||||
*/
|
*/
|
||||||
private void processCategoryConflicts() throws CancelledException {
|
private void processCategoryConflicts() throws CancelledException {
|
||||||
|
|
||||||
for (int i = 0; i < catConflictList.size(); i++) {
|
for (int i = 0; i < catConflictList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = catConflictList.get(i).longValue();
|
long id = catConflictList.get(i).longValue();
|
||||||
|
@ -474,9 +463,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
private void processCategoryChanges() throws CancelledException {
|
private void processCategoryChanges() throws CancelledException {
|
||||||
for (int i = 0; i < myCatChangeList.size(); i++) {
|
for (int i = 0; i < myCatChangeList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = myCatChangeList.get(i).longValue();
|
long id = myCatChangeList.get(i).longValue();
|
||||||
|
@ -489,9 +476,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
private void processCategoriesDeleted() throws CancelledException {
|
private void processCategoriesDeleted() throws CancelledException {
|
||||||
for (int i = 0; i < myCatChangeList.size(); i++) {
|
for (int i = 0; i < myCatChangeList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
long id = myCatChangeList.get(i).longValue();
|
long id = myCatChangeList.get(i).longValue();
|
||||||
processCategoryDeleted(id);
|
processCategoryDeleted(id);
|
||||||
|
@ -500,15 +485,13 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
private void processDataTypeConflicts() throws CancelledException {
|
private void processDataTypeConflicts() throws CancelledException {
|
||||||
while (dtConflictList.size() > 0) {
|
while (dtConflictList.size() > 0) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = dtConflictList.get(0).longValue();
|
long id = dtConflictList.get(0).longValue();
|
||||||
++currentConflictIndex;
|
++currentConflictIndex;
|
||||||
handleDataTypeConflict(id, currentConflictIndex);
|
handleDataTypeConflict(id, currentConflictIndex);
|
||||||
dtConflictList.remove(new Long(id));
|
dtConflictList.remove(Long.valueOf(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
fixUpDataTypes();
|
fixUpDataTypes();
|
||||||
|
@ -530,10 +513,6 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id
|
|
||||||
* @param conflictIndex
|
|
||||||
*/
|
|
||||||
private void handleDataTypeConflict(long id, int conflictIndex) throws CancelledException {
|
private void handleDataTypeConflict(long id, int conflictIndex) throws CancelledException {
|
||||||
|
|
||||||
DataType myDt = dtms[MY].getDataType(id);
|
DataType myDt = dtms[MY].getDataType(id);
|
||||||
|
@ -585,9 +564,6 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id
|
|
||||||
*/
|
|
||||||
private void setSourceDataType(long myID) {
|
private void setSourceDataType(long myID) {
|
||||||
|
|
||||||
DataType myDt = dtms[MY].getDataType(myID);
|
DataType myDt = dtms[MY].getDataType(myID);
|
||||||
|
@ -635,9 +611,6 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id
|
|
||||||
*/
|
|
||||||
private void changeSourceArchive(long dtID) {
|
private void changeSourceArchive(long dtID) {
|
||||||
|
|
||||||
int optionToUse = (dataTypeChoice == ASK_USER) ? conflictOption : dataTypeChoice;
|
int optionToUse = (dataTypeChoice == ASK_USER) ? conflictOption : dataTypeChoice;
|
||||||
|
@ -656,9 +629,6 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param id
|
|
||||||
*/
|
|
||||||
private void dataTypeChanged(long id) {
|
private void dataTypeChanged(long id) {
|
||||||
|
|
||||||
int optionToUse = (dataTypeChoice == ASK_USER) ? conflictOption : dataTypeChoice;
|
int optionToUse = (dataTypeChoice == ASK_USER) ? conflictOption : dataTypeChoice;
|
||||||
|
@ -750,7 +720,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
switch (conflictOption) {
|
switch (conflictOption) {
|
||||||
case OPTION_LATEST:
|
case OPTION_LATEST:
|
||||||
if (latestDt == null) {
|
if (latestDt == null) {
|
||||||
if (!myDtAddedList.contains(new Long(id))) {
|
if (!myDtAddedList.contains(Long.valueOf(id))) {
|
||||||
// remove the data type if it was already added
|
// remove the data type if it was already added
|
||||||
DataType dt = myResolvedDts.get(id);
|
DataType dt = myResolvedDts.get(id);
|
||||||
if (dt != null) {
|
if (dt != null) {
|
||||||
|
@ -781,6 +751,12 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set category path. If name conflict occurs within new category
|
||||||
|
* the specified dt will remain within its' current category
|
||||||
|
* @param dt datatype whoose category is to changed
|
||||||
|
* @param newPath new category path
|
||||||
|
*/
|
||||||
private void setCategoryPath(DataType dt, CategoryPath newPath) {
|
private void setCategoryPath(DataType dt, CategoryPath newPath) {
|
||||||
if (dt.getCategoryPath().equals(newPath)) {
|
if (dt.getCategoryPath().equals(newPath)) {
|
||||||
return;
|
return;
|
||||||
|
@ -789,6 +765,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
dt.setCategoryPath(newPath);
|
dt.setCategoryPath(newPath);
|
||||||
}
|
}
|
||||||
catch (DuplicateNameException e) {
|
catch (DuplicateNameException e) {
|
||||||
|
// ignore - no change made
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,11 +808,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
updateHashTables(id, resultDt, resolvedDataTypes);
|
updateHashTables(id, resultDt, resolvedDataTypes);
|
||||||
if (updatePath && !resultDt.getCategoryPath().equals(myDt.getCategoryPath())) {
|
if (updatePath && !resultDt.getCategoryPath().equals(myDt.getCategoryPath())) {
|
||||||
try {
|
setCategoryPath(resultDt, myDt.getCategoryPath());
|
||||||
resultDt.setCategoryPath(myDt.getCategoryPath());
|
|
||||||
}
|
|
||||||
catch (DuplicateNameException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultDt;
|
return resultDt;
|
||||||
|
@ -883,7 +856,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
return existingDt; // Data type is already resolved and mapped in the table.
|
return existingDt; // Data type is already resolved and mapped in the table.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myDtAddedList.contains(new Long(dataTypeID))) {
|
if (!myDtAddedList.contains(Long.valueOf(dataTypeID))) {
|
||||||
existingDt = dtms[RESULT].getDataType(dataTypeID);
|
existingDt = dtms[RESULT].getDataType(dataTypeID);
|
||||||
if (existingDt != null) {
|
if (existingDt != null) {
|
||||||
Msg.warn(this, " ** WARNING ** : Unexpectedly found data type \"" +
|
Msg.warn(this, " ** WARNING ** : Unexpectedly found data type \"" +
|
||||||
|
@ -936,10 +909,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
if (resolvedDt == null) {
|
if (resolvedDt == null) {
|
||||||
// Haven't resolved this yet.
|
// Haven't resolved this yet.
|
||||||
// use dt from results
|
// use dt from results
|
||||||
if (!myDtAddedList.contains(new Long(baseID))) {
|
if (!myDtAddedList.contains(Long.valueOf(baseID))) {
|
||||||
resolvedDt = dtms[RESULT].getDataType(baseID);
|
resolvedDt = dtms[RESULT].getDataType(baseID);
|
||||||
if (resolvedDt == null) {
|
if (resolvedDt == null) {
|
||||||
if (origDtConflictList.contains(new Long(baseID))) {
|
if (origDtConflictList.contains(Long.valueOf(baseID))) {
|
||||||
// was deleted, but add it back so we can create
|
// was deleted, but add it back so we can create
|
||||||
// data types depending on it; will get resolved later
|
// data types depending on it; will get resolved later
|
||||||
resolvedDt = addDataType(baseID, baseDt, resolvedDataTypes);
|
resolvedDt = addDataType(baseID, baseDt, resolvedDataTypes);
|
||||||
|
@ -1054,11 +1027,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
private DataType addFunctionDef(long id, FunctionDefinition myDt,
|
private DataType addFunctionDef(long id, FunctionDefinition myDt,
|
||||||
LongObjectHashtable<DataType> resolvedDataTypes) {
|
LongObjectHashtable<DataType> resolvedDataTypes) {
|
||||||
FunctionDefinition newDt = (FunctionDefinition) myDt.clone(dtms[RESULT]);
|
FunctionDefinition newDt = (FunctionDefinition) myDt.clone(dtms[RESULT]);
|
||||||
try {
|
setCategoryPath(newDt, myDt.getCategoryPath());
|
||||||
newDt.setCategoryPath(myDt.getCategoryPath());
|
|
||||||
}
|
|
||||||
catch (DuplicateNameException e) {
|
|
||||||
}
|
|
||||||
updateFunctionDef(id, myDt, newDt, resolvedDataTypes);
|
updateFunctionDef(id, myDt, newDt, resolvedDataTypes);
|
||||||
return newDt;
|
return newDt;
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1035,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
private void updateHashTables(long id, DataType newDt,
|
private void updateHashTables(long id, DataType newDt,
|
||||||
LongObjectHashtable<DataType> resolvedDataTypes) {
|
LongObjectHashtable<DataType> resolvedDataTypes) {
|
||||||
resolvedDataTypes.put(id, newDt);
|
resolvedDataTypes.put(id, newDt);
|
||||||
if (!myDtAddedList.contains(new Long(id))) {
|
if (!myDtAddedList.contains(Long.valueOf(id))) {
|
||||||
if (resolvedDataTypes == myResolvedDts) {
|
if (resolvedDataTypes == myResolvedDts) {
|
||||||
origResolvedDts.put(id, newDt);
|
origResolvedDts.put(id, newDt);
|
||||||
latestResolvedDts.put(id, newDt);
|
latestResolvedDts.put(id, newDt);
|
||||||
|
@ -1098,7 +1067,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
if (baseDt != DataType.DEFAULT) {
|
if (baseDt != DataType.DEFAULT) {
|
||||||
DataTypeManager dtm = baseDt.getDataTypeManager();
|
DataTypeManager dtm = baseDt.getDataTypeManager();
|
||||||
long baseID = dtm.getID(baseDt);
|
long baseID = dtm.getID(baseDt);
|
||||||
if (!myDtAddedList.contains(new Long(baseID))) {
|
if (!myDtAddedList.contains(Long.valueOf(baseID))) {
|
||||||
if (dtms[RESULT].getDataType(baseID) != null) {
|
if (dtms[RESULT].getDataType(baseID) != null) {
|
||||||
return resolvedDt;
|
return resolvedDt;
|
||||||
}
|
}
|
||||||
|
@ -1118,15 +1087,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
destStruct.deleteAll();
|
destStruct.deleteAll();
|
||||||
|
|
||||||
// Set to correct alignment and packing.
|
// Set to correct alignment and packing.
|
||||||
try {
|
updateAlignment(sourceDt, destStruct);
|
||||||
updateAlignment(sourceDt, destStruct);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
String msg = "Some of your changes to " + destStruct.getName() +
|
|
||||||
" cannot be merged.\nProblem: " + e.getMessage();
|
|
||||||
Msg.showError(this, null, "Structure Update Failed", msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypeManager sourceDTM = sourceDt.getDataTypeManager();
|
DataTypeManager sourceDTM = sourceDt.getDataTypeManager();
|
||||||
boolean aligned = sourceDt.isInternallyAligned();
|
boolean aligned = sourceDt.isInternallyAligned();
|
||||||
|
@ -1148,7 +1109,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
if (resultCompDt == null) {
|
if (resultCompDt == null) {
|
||||||
// We didn't have a map entry for the data type.
|
// We didn't have a map entry for the data type.
|
||||||
|
|
||||||
if (!myDtAddedList.contains(new Long(sourceComponentID))) {
|
if (!myDtAddedList.contains(Long.valueOf(sourceComponentID))) {
|
||||||
|
|
||||||
// Not added so should be in result if it wasn't deleted there.
|
// Not added so should be in result if it wasn't deleted there.
|
||||||
DataType rDt = dtms[RESULT].getDataType(sourceComponentID);
|
DataType rDt = dtms[RESULT].getDataType(sourceComponentID);
|
||||||
|
@ -1242,15 +1203,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set to correct alignment and packing.
|
// Set to correct alignment and packing.
|
||||||
try {
|
updateAlignment(sourceDt, destUnion);
|
||||||
updateAlignment(sourceDt, destUnion);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
String msg = "Some of your changes to " + destUnion.getName() +
|
|
||||||
" cannot be merged.\nProblem: " + e.getMessage();
|
|
||||||
Msg.showError(this, null, "Union Update Failed", msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypeManager sourceDTM = sourceDt.getDataTypeManager();
|
DataTypeManager sourceDTM = sourceDt.getDataTypeManager();
|
||||||
|
|
||||||
|
@ -1263,7 +1216,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
DataType resultCompDt = getResolvedComponent(sourceCompID, resolvedDataTypes);
|
DataType resultCompDt = getResolvedComponent(sourceCompID, resolvedDataTypes);
|
||||||
|
|
||||||
if (resultCompDt == null) {
|
if (resultCompDt == null) {
|
||||||
if (!myDtAddedList.contains(new Long(sourceCompID))) {
|
if (!myDtAddedList.contains(Long.valueOf(sourceCompID))) {
|
||||||
|
|
||||||
// Not added so should be in result if it wasn't deleted there.
|
// Not added so should be in result if it wasn't deleted there.
|
||||||
DataType resultsDt = dtms[RESULT].getDataType(sourceCompID);
|
DataType resultsDt = dtms[RESULT].getDataType(sourceCompID);
|
||||||
|
@ -1324,8 +1277,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAlignment(Composite sourceDt, Composite destinationDt)
|
private void updateAlignment(Composite sourceDt, Composite destinationDt) {
|
||||||
throws InvalidInputException {
|
|
||||||
if (sourceDt.isDefaultAligned()) {
|
if (sourceDt.isDefaultAligned()) {
|
||||||
destinationDt.setToDefaultAlignment();
|
destinationDt.setToDefaultAlignment();
|
||||||
}
|
}
|
||||||
|
@ -1363,30 +1315,28 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
DataTypeManager sourceDTM = sourceFunctionDefDt.getDataTypeManager();
|
DataTypeManager sourceDTM = sourceFunctionDefDt.getDataTypeManager();
|
||||||
DataType sourceReturnType = sourceFunctionDefDt.getReturnType();
|
DataType sourceReturnType = sourceFunctionDefDt.getReturnType();
|
||||||
ParameterDefinition[] sourceVars = sourceFunctionDefDt.getArguments();
|
ParameterDefinition[] sourceVars = sourceFunctionDefDt.getArguments();
|
||||||
ParameterDefinition[] destVars = destDt.getArguments();
|
ParameterDefinition[] destVars = new ParameterDefinition[sourceVars.length];
|
||||||
boolean sourceHasVarArgs = sourceFunctionDefDt.hasVarArgs();
|
boolean sourceHasVarArgs = sourceFunctionDefDt.hasVarArgs();
|
||||||
|
|
||||||
|
DataType resolvedRDT = DataType.DEFAULT;
|
||||||
if (sourceReturnType != null) {
|
if (sourceReturnType != null) {
|
||||||
long returnTypeID = sourceDTM.getID(sourceReturnType);
|
long returnTypeID = sourceDTM.getID(sourceReturnType);
|
||||||
DataType resolvedRDT =
|
resolvedRDT =
|
||||||
getResolvedParam(sourceFunctionDefDtID, returnTypeID, -1, resolvedDataTypes);
|
getResolvedParam(sourceFunctionDefDtID, returnTypeID, -1, resolvedDataTypes);
|
||||||
destDt.setReturnType(resolvedRDT);
|
|
||||||
}
|
}
|
||||||
|
destDt.setReturnType(resolvedRDT);
|
||||||
|
|
||||||
for (int i = 0; i < sourceVars.length; i++) {
|
for (int i = 0; i < sourceVars.length; i++) {
|
||||||
DataType varDt = sourceVars[i].getDataType();
|
DataType varDt = sourceVars[i].getDataType();
|
||||||
long varID = sourceDTM.getID(varDt);
|
long varID = sourceDTM.getID(varDt);
|
||||||
DataType resolvedDt =
|
DataType resolvedDt =
|
||||||
getResolvedParam(sourceFunctionDefDtID, varID, i, resolvedDataTypes);
|
getResolvedParam(sourceFunctionDefDtID, varID, i, resolvedDataTypes);
|
||||||
destVars[i].setComment(sourceVars[i].getComment());
|
destVars[i] = new ParameterDefinitionImpl(sourceVars[i].getName(), resolvedDt,
|
||||||
try {
|
sourceVars[i].getComment());
|
||||||
destVars[i].setDataType(resolvedDt);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sourceHasVarArgs != destDt.hasVarArgs()) {
|
|
||||||
destDt.setVarArgs(sourceHasVarArgs);
|
|
||||||
}
|
}
|
||||||
|
destDt.setArguments(destVars);
|
||||||
|
destDt.setVarArgs(sourceHasVarArgs);
|
||||||
|
|
||||||
destDt.setLastChangeTime(oldLastChangeTime);
|
destDt.setLastChangeTime(oldLastChangeTime);
|
||||||
destDt.setLastChangeTimeInSourceArchive(oldLastChangeTimeInSourceArchive);
|
destDt.setLastChangeTimeInSourceArchive(oldLastChangeTimeInSourceArchive);
|
||||||
}
|
}
|
||||||
|
@ -1405,7 +1355,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
LongObjectHashtable<DataType> resolvedDataTypes) {
|
LongObjectHashtable<DataType> resolvedDataTypes) {
|
||||||
DataType resolvedDt = getResolvedComponent(paramID, resolvedDataTypes);
|
DataType resolvedDt = getResolvedComponent(paramID, resolvedDataTypes);
|
||||||
if (resolvedDt == null) {
|
if (resolvedDt == null) {
|
||||||
if (!myDtAddedList.contains(new Long(paramID))) {
|
if (!myDtAddedList.contains(Long.valueOf(paramID))) {
|
||||||
|
|
||||||
// Not added so should be in result if it wasn't deleted there.
|
// Not added so should be in result if it wasn't deleted there.
|
||||||
DataType resultsDt = dtms[RESULT].getDataType(paramID);
|
DataType resultsDt = dtms[RESULT].getDataType(paramID);
|
||||||
|
@ -1435,14 +1385,12 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
* Process data types that were changed (renamed, moved, or edited) in
|
* Process data types that were changed (renamed, moved, or edited) in
|
||||||
* MY program, but are not conflicts, i.e., not renamed, moved or edited
|
* MY program, but are not conflicts, i.e., not renamed, moved or edited
|
||||||
* in LATEST. The corresponding data type in RESULT program is updated.
|
* in LATEST. The corresponding data type in RESULT program is updated.
|
||||||
* @throws CancelledException
|
* @throws CancelledException if task is cancelled
|
||||||
*/
|
*/
|
||||||
private void processDataTypeChanges() throws CancelledException {
|
private void processDataTypeChanges() throws CancelledException {
|
||||||
|
|
||||||
for (int i = 0; i < myDtChangeList.size(); i++) {
|
for (int i = 0; i < myDtChangeList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long id = myDtChangeList.get(i).longValue();
|
long id = myDtChangeList.get(i).longValue();
|
||||||
|
@ -1777,8 +1725,8 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
* was moved; if so, move the category according to the conflictOption
|
* was moved; if so, move the category according to the conflictOption
|
||||||
* selected. Moves are handled here because a rename and a move is
|
* selected. Moves are handled here because a rename and a move is
|
||||||
* considered to be a single conflict.
|
* considered to be a single conflict.
|
||||||
* @param id
|
* @param id category ID
|
||||||
* @throws CancelledException
|
* @throws CancelledException if task is cancelled
|
||||||
*/
|
*/
|
||||||
private void categoryRenamedOrMoved(long id) throws CancelledException {
|
private void categoryRenamedOrMoved(long id) throws CancelledException {
|
||||||
|
|
||||||
|
@ -1842,7 +1790,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
* Handle conflicts on a category that was deleted in one program, and
|
* Handle conflicts on a category that was deleted in one program, and
|
||||||
* renamed or moved in another program.
|
* renamed or moved in another program.
|
||||||
* @param id category ID
|
* @param id category ID
|
||||||
* @throws CancelledException
|
* @throws CancelledException if operation is cancelled
|
||||||
*/
|
*/
|
||||||
private void categoryDeleted(long id) throws CancelledException {
|
private void categoryDeleted(long id) throws CancelledException {
|
||||||
|
|
||||||
|
@ -1933,7 +1881,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
if (doDelete) {
|
if (doDelete) {
|
||||||
Category parentCat = dtms[RESULT].getCategory(latestCat.getParent().getCategoryPath());
|
Category parentCat = dtms[RESULT].getCategory(latestCat.getParent().getCategoryPath());
|
||||||
if (parentCat != null) {
|
if (parentCat != null) {
|
||||||
parentCat.removeCategory(latestCat.getName(), TaskMonitorAdapter.DUMMY_MONITOR);
|
parentCat.removeCategory(latestCat.getName(), TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1955,8 +1903,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
mergeManager.setApplyEnabled(false);
|
mergeManager.setApplyEnabled(false);
|
||||||
mergeManager.showComponent(archiveMergePanel, "SourceArchiveMerge",
|
mergeManager.showComponent(archiveMergePanel, "SourceArchiveMerge",
|
||||||
|
@ -1987,8 +1937,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
mergeManager.setApplyEnabled(false);
|
mergeManager.setApplyEnabled(false);
|
||||||
mergeManager.showComponent(catMergePanel, "CategoryMerge",
|
mergeManager.showComponent(catMergePanel, "CategoryMerge",
|
||||||
|
@ -2010,8 +1962,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
mergeManager.showComponent(dtMergePanel, "DataTypeMerge",
|
mergeManager.showComponent(dtMergePanel, "DataTypeMerge",
|
||||||
new HelpLocation(HelpTopics.REPOSITORY, "DataTypeConflicts"));
|
new HelpLocation(HelpTopics.REPOSITORY, "DataTypeConflicts"));
|
||||||
|
@ -2024,9 +1978,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
|
|
||||||
private void processDataTypesDeleted() throws CancelledException {
|
private void processDataTypesDeleted() throws CancelledException {
|
||||||
for (int i = 0; i < myDtChangeList.size(); i++) {
|
for (int i = 0; i < myDtChangeList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
long id = myDtChangeList.get(i).longValue();
|
long id = myDtChangeList.get(i).longValue();
|
||||||
processDataTypeDeleted(id);
|
processDataTypeDeleted(id);
|
||||||
|
@ -2038,9 +1990,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
*/
|
*/
|
||||||
private void processDataTypesAdded() throws CancelledException {
|
private void processDataTypesAdded() throws CancelledException {
|
||||||
for (int i = 0; i < myDtAddedList.size(); i++) {
|
for (int i = 0; i < myDtAddedList.size(); i++) {
|
||||||
if (currentMonitor.isCancelled()) {
|
currentMonitor.checkCanceled();
|
||||||
throw new CancelledException();
|
|
||||||
}
|
|
||||||
currentMonitor.setProgress(++progressIndex);
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
|
||||||
long myDtKey = myDtAddedList.get(i).longValue();
|
long myDtKey = myDtAddedList.get(i).longValue();
|
||||||
|
@ -2160,11 +2110,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ParameterDefinition[] vars = fd.getArguments();
|
ParameterDefinition[] vars = fd.getArguments();
|
||||||
try {
|
vars[info.index].setDataType(dt);
|
||||||
vars[info.index].setDataType(dt);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fd.setLastChangeTime(lastChangeTime); // Reset the last change time to the merged data type's.
|
fd.setLastChangeTime(lastChangeTime); // Reset the last change time to the merged data type's.
|
||||||
|
@ -2393,7 +2339,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!myDtAddedList.contains(new Long(id))) {
|
if (!myDtAddedList.contains(Long.valueOf(id))) {
|
||||||
// use data type from RESULT
|
// use data type from RESULT
|
||||||
return dtms[RESULT].getDataType(id);
|
return dtms[RESULT].getDataType(id);
|
||||||
}
|
}
|
||||||
|
@ -2507,7 +2453,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
long[] myArchiveChanges) {
|
long[] myArchiveChanges) {
|
||||||
for (long myChangeID : myArchiveChanges) {
|
for (long myChangeID : myArchiveChanges) {
|
||||||
UniversalID sourceID = new UniversalID(myChangeID);
|
UniversalID sourceID = new UniversalID(myChangeID);
|
||||||
Long myChangeIDObject = new Long(myChangeID);
|
Long myChangeIDObject = Long.valueOf(myChangeID);
|
||||||
if (myArchiveAddedList.contains(myChangeIDObject) ||
|
if (myArchiveAddedList.contains(myChangeIDObject) ||
|
||||||
archiveConflictList.contains(myChangeIDObject)) {
|
archiveConflictList.contains(myChangeIDObject)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2550,7 +2496,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myArchiveChangeList.add(new Long(myChangeID));
|
myArchiveChangeList.add(Long.valueOf(myChangeID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2572,14 +2518,14 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
dtms[LATEST].getSourceArchive(new UniversalID(latestAddID));
|
dtms[LATEST].getSourceArchive(new UniversalID(latestAddID));
|
||||||
if (!StringUtils.equals(mySourceArchive.getName(),
|
if (!StringUtils.equals(mySourceArchive.getName(),
|
||||||
latestSourceArchive.getName())) {
|
latestSourceArchive.getName())) {
|
||||||
archiveConflictList.add(new Long(myAddID));
|
archiveConflictList.add(Long.valueOf(myAddID));
|
||||||
foundConflict = true;
|
foundConflict = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!foundConflict) {
|
if (!foundConflict) {
|
||||||
myArchiveAddedList.add(new Long(myAddID));
|
myArchiveAddedList.add(Long.valueOf(myAddID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2593,7 +2539,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
boolean latestDirty =
|
boolean latestDirty =
|
||||||
(latestSourceArchive != null) ? latestSourceArchive.isDirty() : false;
|
(latestSourceArchive != null) ? latestSourceArchive.isDirty() : false;
|
||||||
boolean myDirty = mySourceArchive.isDirty();
|
boolean myDirty = mySourceArchive.isDirty();
|
||||||
dirtyMap.put(sourceID, new Boolean(myDirty || latestDirty));
|
dirtyMap.put(sourceID, Boolean.valueOf(myDirty || latestDirty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2618,18 +2564,18 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
dtSourceConflictList = new ArrayList<>();
|
dtSourceConflictList = new ArrayList<>();
|
||||||
myDtChangeList = new ArrayList<>();
|
myDtChangeList = new ArrayList<>();
|
||||||
for (long myDtChange : myDtChanges) {
|
for (long myDtChange : myDtChanges) {
|
||||||
myDtChangeList.add(new Long(myDtChange));
|
myDtChangeList.add(Long.valueOf(myDtChange));
|
||||||
}
|
}
|
||||||
|
|
||||||
processAddIDs(myDtAdds);
|
processAddIDs(myDtAdds);
|
||||||
|
|
||||||
ArrayList<Long> resultDtChangeList = new ArrayList<>();
|
ArrayList<Long> resultDtChangeList = new ArrayList<>();
|
||||||
for (long latestDtChange : latestDtChanges) {
|
for (long latestDtChange : latestDtChanges) {
|
||||||
resultDtChangeList.add(new Long(latestDtChange));
|
resultDtChangeList.add(Long.valueOf(latestDtChange));
|
||||||
}
|
}
|
||||||
ArrayList<Long> resultDtAddList = new ArrayList<>();
|
ArrayList<Long> resultDtAddList = new ArrayList<>();
|
||||||
for (long latestDtAdd : latestDtAdds) {
|
for (long latestDtAdd : latestDtAdds) {
|
||||||
resultDtAddList.add(new Long(latestDtAdd));
|
resultDtAddList.add(Long.valueOf(latestDtAdd));
|
||||||
}
|
}
|
||||||
// remove my Added dt's from my changed dt's
|
// remove my Added dt's from my changed dt's
|
||||||
// Added and then changed data types should only be in added.
|
// Added and then changed data types should only be in added.
|
||||||
|
@ -2683,15 +2629,15 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
!DataTypeUtilities.equalsIgnoreConflict(resultDt.getName(),
|
!DataTypeUtilities.equalsIgnoreConflict(resultDt.getName(),
|
||||||
myDt.getName()) ||
|
myDt.getName()) ||
|
||||||
!resultDt.isEquivalent(myDt)) {
|
!resultDt.isEquivalent(myDt)) {
|
||||||
dtConflictList.add(new Long(myDtAdd));
|
dtConflictList.add(Long.valueOf(myDtAdd));
|
||||||
dtSourceConflictList.add(new Long(myDtAdd));
|
dtSourceConflictList.add(Long.valueOf(myDtAdd));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myDtAddedList.add(new Long(myDtAdd));
|
myDtAddedList.add(Long.valueOf(myDtAdd));
|
||||||
}
|
}
|
||||||
else { // Added and then removed data types go on the change list.
|
else { // Added and then removed data types go on the change list.
|
||||||
Long l = new Long(myDtAdd);
|
Long l = Long.valueOf(myDtAdd);
|
||||||
if (!myDtChangeList.contains(l)) {
|
if (!myDtChangeList.contains(l)) {
|
||||||
myDtChangeList.add(l);
|
myDtChangeList.add(l);
|
||||||
}
|
}
|
||||||
|
@ -2762,7 +2708,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
// Just need the change from My.
|
// Just need the change from My.
|
||||||
dtConflictList.remove(i);
|
dtConflictList.remove(i);
|
||||||
if (myChanged || renamedMy || mySourceChanged) {
|
if (myChanged || renamedMy || mySourceChanged) {
|
||||||
myDtChangeList.add(new Long(id));
|
myDtChangeList.add(Long.valueOf(id));
|
||||||
}
|
}
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
@ -2786,7 +2732,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
long[] myCatChanges = myChanges.getCategoryChanges();
|
long[] myCatChanges = myChanges.getCategoryChanges();
|
||||||
Arrays.sort(myCatChanges);
|
Arrays.sort(myCatChanges);
|
||||||
for (long myCatChange : myCatChanges) {
|
for (long myCatChange : myCatChanges) {
|
||||||
myCatChangeList.add(new Long(myCatChange));
|
myCatChangeList.add(Long.valueOf(myCatChange));
|
||||||
}
|
}
|
||||||
|
|
||||||
myCatAddedList = new ArrayList<>();
|
myCatAddedList = new ArrayList<>();
|
||||||
|
@ -2794,10 +2740,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
Arrays.sort(myCatAdds);
|
Arrays.sort(myCatAdds);
|
||||||
for (long myCatAdd : myCatAdds) {
|
for (long myCatAdd : myCatAdds) {
|
||||||
if (dtms[MY].getCategory(myCatAdd) != null) {
|
if (dtms[MY].getCategory(myCatAdd) != null) {
|
||||||
myCatAddedList.add(new Long(myCatAdd));
|
myCatAddedList.add(Long.valueOf(myCatAdd));
|
||||||
}
|
}
|
||||||
else { // Added and then removed categories go on the change list.
|
else { // Added and then removed categories go on the change list.
|
||||||
Long l = new Long(myCatAdd);
|
Long l = Long.valueOf(myCatAdd);
|
||||||
if (!myCatChangeList.contains(l)) {
|
if (!myCatChangeList.contains(l)) {
|
||||||
myCatChangeList.add(l);
|
myCatChangeList.add(l);
|
||||||
}
|
}
|
||||||
|
@ -2809,7 +2755,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
Arrays.sort(latestCatChanges);
|
Arrays.sort(latestCatChanges);
|
||||||
ArrayList<Long> resultCatChangeList = new ArrayList<>();
|
ArrayList<Long> resultCatChangeList = new ArrayList<>();
|
||||||
for (long latestCatChange : latestCatChanges) {
|
for (long latestCatChange : latestCatChanges) {
|
||||||
resultCatChangeList.add(new Long(latestCatChange));
|
resultCatChangeList.add(Long.valueOf(latestCatChange));
|
||||||
}
|
}
|
||||||
// remove my Added categories from my changed categories
|
// remove my Added categories from my changed categories
|
||||||
// Added and then changed categories should only be in added.
|
// Added and then changed categories should only be in added.
|
||||||
|
@ -2853,7 +2799,7 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (renamedMy) { // Renamed My category without conflict.
|
if (renamedMy) { // Renamed My category without conflict.
|
||||||
myCatChangeList.add(new Long(id));
|
myCatChangeList.add(Long.valueOf(id));
|
||||||
}
|
}
|
||||||
catConflictList.remove(i); // remove ID from conflicts since not actually in conflict.
|
catConflictList.remove(i); // remove ID from conflicts since not actually in conflict.
|
||||||
--i;
|
--i;
|
||||||
|
@ -2894,8 +2840,10 @@ public class DataTypeMergeManager implements MergeResolver {
|
||||||
SwingUtilities.invokeAndWait(() -> Msg.showInfo(getClass(), null, title, msg));
|
SwingUtilities.invokeAndWait(() -> Msg.showInfo(getClass(), null, title, msg));
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ public abstract class AbstractDataTypeMergeTest extends AbstractMergeTest {
|
||||||
if (option >= 0) {
|
if (option >= 0) {
|
||||||
dataTypeMergeManager.setConflictResolution(option);
|
dataTypeMergeManager.setConflictResolution(option);
|
||||||
}
|
}
|
||||||
dataTypeMergeManager.merge(TaskMonitorAdapter.DUMMY_MONITOR);
|
dataTypeMergeManager.merge(TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Window getMergeWindow(CountDownLatch doneLatch) {
|
private Window getMergeWindow(CountDownLatch doneLatch) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
import ghidra.util.InvalidNameException;
|
import ghidra.util.InvalidNameException;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for merging data types.
|
* Tests for merging data types.
|
||||||
|
@ -1198,7 +1198,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||||
try {
|
try {
|
||||||
// remove Bar from the data type manager
|
// remove Bar from the data type manager
|
||||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1290,7 +1290,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||||
try {
|
try {
|
||||||
// remove Bar from the data type manager
|
// remove Bar from the data type manager
|
||||||
dtm.remove(bar, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1430,7 +1430,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
try {
|
try {
|
||||||
fd.setReturnType(bar);
|
fd.setReturnType(bar);
|
||||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1498,7 +1498,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
try {
|
try {
|
||||||
fd.setVarArgs(true);
|
fd.setVarArgs(true);
|
||||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1567,7 +1567,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
try {
|
try {
|
||||||
fd.setVarArgs(true);
|
fd.setVarArgs(true);
|
||||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||||
dtm.remove(foo, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(foo, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1620,6 +1620,79 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
||||||
assertEquals(true, fd.hasVarArgs());
|
assertEquals(true, fd.hasVarArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEditFuncSig5() throws Exception {
|
||||||
|
|
||||||
|
mtf.initialize("notepad3", new ProgramModifierListener() {
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void modifyLatest(ProgramDB program) throws Exception {
|
||||||
|
boolean commit = false;
|
||||||
|
DataTypeManager dtm = program.getDataTypeManager();
|
||||||
|
int transactionID = program.startTransaction("test");
|
||||||
|
|
||||||
|
FunctionDefinition fd =
|
||||||
|
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"),
|
||||||
|
"MyFunctionDef");
|
||||||
|
|
||||||
|
try {
|
||||||
|
fd.setReturnType(VoidDataType.dataType);
|
||||||
|
|
||||||
|
commit = true;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
program.endTransaction(transactionID, commit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||||
|
boolean commit = false;
|
||||||
|
DataTypeManager dtm = program.getDataTypeManager();
|
||||||
|
|
||||||
|
FunctionDefinition fd =
|
||||||
|
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"),
|
||||||
|
"MyFunctionDef");
|
||||||
|
ParameterDefinition[] vars = fd.getArguments();
|
||||||
|
|
||||||
|
int transactionID = program.startTransaction("test");
|
||||||
|
try {
|
||||||
|
ParameterDefinition[] newVars = new ParameterDefinition[vars.length + 1];
|
||||||
|
System.arraycopy(vars, 0, newVars, 0, vars.length);
|
||||||
|
newVars[vars.length] = new ParameterDefinitionImpl("Bar", WordDataType.dataType,
|
||||||
|
"this is another comment");
|
||||||
|
fd.setArguments(newVars);
|
||||||
|
fd.setVarArgs(true);
|
||||||
|
commit = true;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
program.endTransaction(transactionID, commit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
executeMerge(DataTypeMergeManager.OPTION_MY);
|
||||||
|
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||||
|
FunctionDefinition fd =
|
||||||
|
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"), "MyFunctionDef");
|
||||||
|
assertNotNull(fd);
|
||||||
|
Structure dll = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
|
assertEquals(dll, fd.getReturnType());
|
||||||
|
ParameterDefinition[] vars = fd.getArguments();
|
||||||
|
assertTrue(vars[0].getDataType() instanceof WordDataType);
|
||||||
|
assertTrue(vars[1].getDataType() instanceof CharDataType);
|
||||||
|
assertTrue(vars[2].getDataType() instanceof Undefined4DataType);
|
||||||
|
assertTrue(vars[3].getDataType() instanceof Undefined4DataType);
|
||||||
|
assertTrue(vars[4].getDataType() instanceof WordDataType);
|
||||||
|
assertEquals("Bar", vars[4].getName());
|
||||||
|
assertEquals("this is another comment", vars[4].getComment());
|
||||||
|
assertTrue(fd.hasVarArgs());
|
||||||
|
}
|
||||||
|
|
||||||
private void checkDataType(DataType expectedDataType, DataType actualDataType) {
|
private void checkDataType(DataType expectedDataType, DataType actualDataType) {
|
||||||
assertTrue("Expected " + expectedDataType + ", but is " + actualDataType + ".",
|
assertTrue("Expected " + expectedDataType + ", but is " + actualDataType + ".",
|
||||||
actualDataType.isEquivalent(expectedDataType));
|
actualDataType.isEquivalent(expectedDataType));
|
||||||
|
|
|
@ -85,9 +85,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.data.DataType#isDynamicallySized()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDynamicallySized() {
|
public boolean isDynamicallySized() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -142,9 +139,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getArguments()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ParameterDefinition[] getArguments() {
|
public ParameterDefinition[] getArguments() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -157,9 +151,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getReturnType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public DataType getReturnType() {
|
public DataType getReturnType() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -168,7 +159,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
long dtId = record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL);
|
long dtId = record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL);
|
||||||
DataType dt = dataMgr.getDataType(dtId);
|
DataType dt = dataMgr.getDataType(dtId);
|
||||||
if (dt == null) {
|
if (dt == null) {
|
||||||
dt = DataType.VOID;
|
dt = DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
@ -187,12 +178,16 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
|
|
||||||
private void doReplaceWith(FunctionDefinition functionDefinition) {
|
private void doReplaceWith(FunctionDefinition functionDefinition) {
|
||||||
setArguments(functionDefinition.getArguments());
|
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
|
@Override
|
||||||
public String getComment() {
|
public String getComment() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -216,49 +211,31 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getMnemonic(ghidra.program.model.data.Settings)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getMnemonic(Settings settings) {
|
public String getMnemonic(Settings settings) {
|
||||||
return getPrototypeString();
|
return getPrototypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getLength()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getDescription()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Function Signature Data Type";
|
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
|
@Override
|
||||||
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
||||||
return null;
|
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
|
@Override
|
||||||
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
||||||
return getPrototypeString();
|
return getPrototypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setArguments(ghidra.program.model.listing.Variable[])
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setArguments(ParameterDefinition[] args) {
|
public void setArguments(ParameterDefinition[] args) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -272,17 +249,15 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
parameters.clear();
|
parameters.clear();
|
||||||
for (int i = 0; i < args.length; i++) {
|
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(),
|
paramAdapter.createRecord(dataMgr.getID(resolvedDt), key, i, args[i].getName(),
|
||||||
args[i].getComment(), args[i].getLength());
|
args[i].getComment(), args[i].getLength());
|
||||||
|
resolvedDt.addParent(this);
|
||||||
}
|
}
|
||||||
getParameters();
|
getParameters();
|
||||||
it = parameters.iterator();
|
funDefAdapter.updateRecord(record, true); // update last change time
|
||||||
while (it.hasNext()) {
|
|
||||||
ParameterDefinitionDB param = it.next();
|
|
||||||
param.getDataType().addParent(this);
|
|
||||||
}
|
|
||||||
funDefAdapter.updateRecord(record, true);
|
|
||||||
dataMgr.dataTypeChanged(this);
|
dataMgr.dataTypeChanged(this);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
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
|
@Override
|
||||||
public void setReturnType(DataType type) {
|
public void setReturnType(DataType type) {
|
||||||
|
type = ParameterDefinitionImpl.checkDataType(type, dataMgr, true);
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
getReturnType().removeParent(this);
|
getReturnType().removeParent(this);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
type = DataType.VOID;
|
type = DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
DataType resolvedDt = resolve(type);
|
DataType resolvedDt = 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);
|
||||||
dataMgr.dataTypeChanged(this);
|
|
||||||
resolvedDt.addParent(this);
|
resolvedDt.addParent(this);
|
||||||
|
dataMgr.dataTypeChanged(this);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
dataMgr.dbError(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
|
@Override
|
||||||
public void setComment(String comment) {
|
public void setComment(String comment) {
|
||||||
lock.acquire();
|
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
|
@Override
|
||||||
public void dataTypeDeleted(DataType dt) {
|
public void dataTypeDeleted(DataType dt) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -352,13 +319,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
ParameterDefinitionDB param = parameters.get(i);
|
ParameterDefinitionDB param = parameters.get(i);
|
||||||
if (param.getDataType() == dt) {
|
if (param.getDataType() == dt) {
|
||||||
dt.removeParent(this);
|
|
||||||
param.setDataType(DataType.DEFAULT);
|
param.setDataType(DataType.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dt == getReturnType()) {
|
if (dt == getReturnType()) {
|
||||||
dt.removeParent(this);
|
setReturnType(DataType.DEFAULT);
|
||||||
setReturnType(DataType.VOID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
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
|
@Override
|
||||||
public boolean isEquivalent(DataType dt) {
|
public boolean isEquivalent(DataType dt) {
|
||||||
if (dt == this) {
|
if (dt == this) {
|
||||||
|
@ -416,46 +378,50 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.data.DataType#setCategoryPath(ghidra.program.model.data.CategoryPath)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void doSetCategoryPathRecord(long categoryID) throws IOException {
|
protected void doSetCategoryPathRecord(long categoryID) throws IOException {
|
||||||
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_CAT_ID_COL, categoryID);
|
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_CAT_ID_COL, categoryID);
|
||||||
funDefAdapter.updateRecord(record, false);
|
funDefAdapter.updateRecord(record, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.data.DataType#setName(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void doSetNameRecord(String name) throws IOException {
|
protected void doSetNameRecord(String name) throws IOException {
|
||||||
record.setString(FunctionDefinitionDBAdapter.FUNCTION_DEF_NAME_COL, name);
|
record.setString(FunctionDefinitionDBAdapter.FUNCTION_DEF_NAME_COL, name);
|
||||||
funDefAdapter.updateRecord(record, true);
|
funDefAdapter.updateRecord(record, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.data.DataType#dataTypeReplaced(ghidra.program.model.data.DataType, ghidra.program.model.data.DataType)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkDeleted();
|
checkDeleted();
|
||||||
if (newDt == this) {
|
if (newDt == this) {
|
||||||
|
// TODO: document why this is neccessary
|
||||||
newDt = DataType.DEFAULT;
|
newDt = DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
DataType retType = getReturnType();
|
DataType retType = getReturnType();
|
||||||
if (oldDt == retType) {
|
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();
|
int n = parameters.size();
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
ParameterDefinitionDB param = parameters.get(i);
|
ParameterDefinitionDB param = parameters.get(i);
|
||||||
if (param.getDataType() == oldDt) {
|
if (param.getDataType() == oldDt) {
|
||||||
oldDt.removeParent(this);
|
try {
|
||||||
param.setDataType(newDt);
|
param.setDataType(newDt);
|
||||||
newDt.addParent(this);
|
}
|
||||||
|
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
|
@Override
|
||||||
public void replaceArgument(int ordinal, String name, DataType dt, String comment,
|
public void replaceArgument(int ordinal, String name, DataType dt, String comment,
|
||||||
SourceType source) {
|
SourceType source) {
|
||||||
//TODO:
|
|
||||||
if (dt.getLength() <= 0) {
|
if (dt.getLength() <= 0) {
|
||||||
throw new IllegalArgumentException("Fixed length data type expected");
|
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
|
@Override
|
||||||
public void dataTypeNameChanged(DataType dt, String oldName) {
|
public void dataTypeNameChanged(DataType dt, String oldName) {
|
||||||
// don't care
|
// don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#hasVarArgs()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasVarArgs() {
|
public boolean hasVarArgs() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -526,9 +485,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setVarArgs(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setVarArgs(boolean hasVarArgs) {
|
public void setVarArgs(boolean hasVarArgs) {
|
||||||
lock.acquire();
|
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
|
@Override
|
||||||
public void setGenericCallingConvention(GenericCallingConvention genericCallingConvention) {
|
public void setGenericCallingConvention(GenericCallingConvention genericCallingConvention) {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -587,9 +540,6 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getGenericCallingConvention()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public GenericCallingConvention getGenericCallingConvention() {
|
public GenericCallingConvention getGenericCallingConvention() {
|
||||||
lock.acquire();
|
lock.acquire();
|
||||||
|
@ -609,17 +559,11 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getLastChangeTime()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastChangeTime() {
|
public long getLastChangeTime() {
|
||||||
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_LAST_CHANGE_TIME_COL);
|
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_LAST_CHANGE_TIME_COL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getSourceSyncTime()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public long getLastChangeTimeInSourceArchive() {
|
public long getLastChangeTimeInSourceArchive() {
|
||||||
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_SOURCE_SYNC_TIME_COL);
|
return record.getLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_SOURCE_SYNC_TIME_COL);
|
||||||
|
|
|
@ -64,7 +64,13 @@ final class ParameterDefinitionDB implements ParameterDefinition {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDataType(DataType type) {
|
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,
|
record.setLongValue(FunctionParameterAdapter.PARAMETER_DT_ID_COL,
|
||||||
dataMgr.getResolvedID(type));
|
dataMgr.getResolvedID(type));
|
||||||
record.setIntValue(FunctionParameterAdapter.PARAMETER_DT_LENGTH_COL, type.getLength());
|
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);
|
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
|
@Override
|
||||||
public boolean isEquivalent(Variable otherVar) {
|
public boolean isEquivalent(Variable otherVar) {
|
||||||
if (otherVar == null) {
|
if (otherVar == null) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ public interface FunctionDefinition extends DataType, FunctionSignature {
|
||||||
/**
|
/**
|
||||||
* Set the return data type for this function
|
* Set the return data type for this function
|
||||||
* @param type the return datatype to be set.
|
* @param type the return datatype to be set.
|
||||||
|
* @throws IllegalArgumentException if data type is not a fixed length type
|
||||||
*/
|
*/
|
||||||
public void setReturnType(DataType 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.mem.MemBuffer;
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.util.UniversalID;
|
import ghidra.util.UniversalID;
|
||||||
import ghidra.util.exception.AssertException;
|
|
||||||
import ghidra.util.exception.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of a function for things like function pointers.
|
* Definition of a function for things like function pointers.
|
||||||
*/
|
*/
|
||||||
public class FunctionDefinitionDataType extends GenericDataType implements FunctionDefinition {
|
public class FunctionDefinitionDataType extends GenericDataType implements FunctionDefinition {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private DataType returnType = DataType.DEFAULT;
|
private DataType returnType = DataType.DEFAULT;
|
||||||
private ParameterDefinition[] params;
|
private ParameterDefinition[] params;
|
||||||
private String comment;
|
private String comment;
|
||||||
|
@ -77,8 +74,8 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
public FunctionDefinitionDataType(CategoryPath path, String name, FunctionSignature sig,
|
public FunctionDefinitionDataType(CategoryPath path, String name, FunctionSignature sig,
|
||||||
UniversalID universalID, SourceArchive sourceArchive, long lastChangeTime,
|
UniversalID universalID, SourceArchive sourceArchive, long lastChangeTime,
|
||||||
long lastChangeTimeInSourceArchive, DataTypeManager dtm) {
|
long lastChangeTimeInSourceArchive, DataTypeManager dtm) {
|
||||||
super(path, name, universalID, sourceArchive, lastChangeTime,
|
super(path, name, universalID, sourceArchive, lastChangeTime, lastChangeTimeInSourceArchive,
|
||||||
lastChangeTimeInSourceArchive, dtm);
|
dtm);
|
||||||
init(sig);
|
init(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,82 +132,40 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sig
|
|
||||||
*/
|
|
||||||
private void copySignature(FunctionSignature sig) {
|
private void copySignature(FunctionSignature sig) {
|
||||||
comment = sig.getComment();
|
comment = sig.getComment();
|
||||||
DataType rtnType = sig.getReturnType();
|
DataType rtnType = sig.getReturnType();
|
||||||
if (rtnType == null) {
|
|
||||||
rtnType = DataType.DEFAULT;
|
|
||||||
}
|
|
||||||
setReturnType(rtnType.clone(getDataTypeManager()));
|
setReturnType(rtnType.clone(getDataTypeManager()));
|
||||||
setArguments(sig.getArguments());
|
setArguments(sig.getArguments());
|
||||||
hasVarArgs = sig.hasVarArgs();
|
hasVarArgs = sig.hasVarArgs();
|
||||||
genericCallingConvention = sig.getGenericCallingConvention();
|
genericCallingConvention = sig.getGenericCallingConvention();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setArguments(ghidra.program.model.listing.ParameterDefinition[])
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setArguments(ParameterDefinition[] args) {
|
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];
|
params = new ParameterDefinition[args.length];
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
DataType dt = args[i].getDataType();
|
DataType dt = args[i].getDataType();
|
||||||
dt.addParent(this);
|
params[i] = new ParameterDefinitionImpl(args[i].getName(),
|
||||||
params[i] =
|
dt.clone(getDataTypeManager()), args[i].getComment(), i);
|
||||||
new ParameterDefinitionImpl(args[i].getName(), dt.clone(getDataTypeManager()),
|
|
||||||
args[i].getComment(), i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.data.DataType#isDynamicallySized()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDynamicallySized() {
|
public boolean isDynamicallySized() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setReturnType(ghidra.program.model.data.DataType)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setReturnType(DataType type) {
|
public void setReturnType(DataType type) {
|
||||||
if (type == null || type.getLength() < 0) {
|
returnType = ParameterDefinitionImpl.checkDataType(type, dataMgr, true);
|
||||||
returnType = DataType.DEFAULT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
returnType.removeParent(this);
|
|
||||||
}
|
|
||||||
returnType = type;
|
|
||||||
if (returnType != null) {
|
|
||||||
returnType.addParent(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setComment(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setComment(String comment) {
|
public void setComment(String comment) {
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.FunctionDefinition#setVarArgs(boolean)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void setVarArgs(boolean hasVarArgs) {
|
public void setVarArgs(boolean hasVarArgs) {
|
||||||
this.hasVarArgs = hasVarArgs;
|
this.hasVarArgs = hasVarArgs;
|
||||||
|
@ -241,41 +196,26 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
getSourceArchive(), getLastChangeTime(), getLastChangeTimeInSourceArchive(), dtm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getMnemonic(ghidra.program.model.data.Settings)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getMnemonic(Settings settings) {
|
public String getMnemonic(Settings settings) {
|
||||||
return getPrototypeString();
|
return getPrototypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getLength()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#getDescription()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Function: " + getMnemonic(null);
|
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
|
@Override
|
||||||
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
||||||
return null;
|
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
|
@Override
|
||||||
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
|
||||||
|
|
||||||
|
@ -320,9 +260,6 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getArguments()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public ParameterDefinition[] getArguments() {
|
public ParameterDefinition[] getArguments() {
|
||||||
ParameterDefinition[] args = new ParameterDefinition[params.length];
|
ParameterDefinition[] args = new ParameterDefinition[params.length];
|
||||||
|
@ -330,25 +267,16 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getReturnType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public DataType getReturnType() {
|
public DataType getReturnType() {
|
||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#getComment()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getComment() {
|
public String getComment() {
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.listing.FunctionSignature#hasVarArgs()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasVarArgs() {
|
public boolean hasVarArgs() {
|
||||||
return hasVarArgs;
|
return hasVarArgs;
|
||||||
|
@ -405,30 +333,37 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#dataTypeReplaced(ghidra.program.model.data.DataType, ghidra.program.model.data.DataType)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
public void dataTypeReplaced(DataType oldDt, DataType newDt) {
|
||||||
if (returnType == oldDt) {
|
|
||||||
oldDt.removeParent(this);
|
if (newDt == this) {
|
||||||
returnType = newDt;
|
// TODO: document why this is neccessary
|
||||||
newDt.addParent(this);
|
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++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
ParameterDefinition param = params[i];
|
ParameterDefinition param = params[i];
|
||||||
if (param.getDataType() == oldDt) {
|
if (param.getDataType() == oldDt) {
|
||||||
oldDt.removeParent(this);
|
|
||||||
try {
|
try {
|
||||||
param.setDataType(newDt);
|
param.setDataType(newDt);
|
||||||
}
|
}
|
||||||
catch (InvalidInputException e) {
|
catch (IllegalArgumentException e) {
|
||||||
throw new IllegalArgumentException(e.getMessage());
|
// oldDt replaced with incompatible type - treat as removal
|
||||||
|
dataTypeDeleted(oldDt);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
newDt.addParent(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -439,57 +374,36 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
||||||
ParameterDefinition[] newParams = new ParameterDefinition[ordinal + 1];
|
ParameterDefinition[] newParams = new ParameterDefinition[ordinal + 1];
|
||||||
System.arraycopy(params, 0, newParams, 0, params.length);
|
System.arraycopy(params, 0, newParams, 0, params.length);
|
||||||
for (int i = params.length; i < ordinal + 1; i++) {
|
for (int i = params.length; i < ordinal + 1; i++) {
|
||||||
newParams[i] =
|
newParams[i] = new ParameterDefinitionImpl(Function.DEFAULT_PARAM_PREFIX + (i + 1),
|
||||||
new ParameterDefinitionImpl(Function.DEFAULT_PARAM_PREFIX + (i + 1),
|
DataType.DEFAULT, newComment, i);
|
||||||
DataType.DEFAULT, newComment, i);
|
|
||||||
}
|
}
|
||||||
params = newParams;
|
params = newParams;
|
||||||
}
|
}
|
||||||
params[ordinal].getDataType().removeParent(this);
|
|
||||||
params[ordinal] = new ParameterDefinitionImpl(newName, dt, newComment, ordinal);
|
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
|
@Override
|
||||||
public void dataTypeSizeChanged(DataType dt) {
|
public void dataTypeSizeChanged(DataType dt) {
|
||||||
|
// ignore - no affect
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#dataTypeDeleted(ghidra.program.model.data.DataType)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dataTypeDeleted(DataType dt) {
|
public void dataTypeDeleted(DataType dt) {
|
||||||
if (returnType == dt) {
|
if (returnType == dt) {
|
||||||
dt.removeParent(this);
|
returnType = DataType.DEFAULT;
|
||||||
returnType = new VoidDataType();
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
if (params[i].getDataType() == dt) {
|
if (params[i].getDataType() == dt) {
|
||||||
try {
|
params[i].setDataType(DataType.DEFAULT);
|
||||||
params[i].setDataType(DataType.DEFAULT);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
throw new AssertException(
|
|
||||||
"Setting DataType to Default should not throw this exception");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.program.model.data.DataType#dataTypeNameChanged(ghidra.program.model.data.DataType, java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dataTypeNameChanged(DataType dt, String oldName) {
|
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
|
@Override
|
||||||
public boolean dependsOn(DataType dt) {
|
public boolean dependsOn(DataType dt) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.model.data;
|
package ghidra.program.model.data;
|
||||||
|
|
||||||
|
import ghidra.program.model.listing.Parameter;
|
||||||
import ghidra.program.model.listing.Variable;
|
import ghidra.program.model.listing.Variable;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>ParameterDefinition</code> specifies a parameter which can be
|
* <code>ParameterDefinition</code> specifies a parameter which can be
|
||||||
|
@ -25,7 +25,9 @@ import ghidra.util.exception.InvalidInputException;
|
||||||
public interface ParameterDefinition extends Comparable<ParameterDefinition> {
|
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();
|
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.
|
* Set the Data Type of this variable. The given dataType must have a fixed length.
|
||||||
* @param type the data type
|
* @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.
|
* Get the Name of this variable.
|
||||||
|
@ -77,16 +79,22 @@ public interface ParameterDefinition extends Comparable<ParameterDefinition> {
|
||||||
public void setComment(String comment);
|
public void setComment(String comment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the specified variable
|
* Determine if a variable corresponds to a parameter which is equivelent to
|
||||||
* represents the same parameter by ordinal
|
* this parameter definition by both ordinal and datatype. Name is not considered
|
||||||
* and dataType
|
* 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);
|
public boolean isEquivalent(Variable variable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the specified parameter definition
|
* Determine if parm is equivelent to this parameter definition by both ordinal
|
||||||
* represents the same parameter by ordinal
|
* and datatype. Name is not considered relavent.
|
||||||
* and dataType
|
* @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);
|
public boolean isEquivalent(ParameterDefinition parm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.model.data;
|
package ghidra.program.model.data;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import ghidra.program.database.data.DataTypeUtilities;
|
import ghidra.program.database.data.DataTypeUtilities;
|
||||||
import ghidra.program.model.listing.Parameter;
|
import ghidra.program.model.listing.Parameter;
|
||||||
import ghidra.program.model.listing.Variable;
|
import ghidra.program.model.listing.Variable;
|
||||||
import ghidra.program.model.symbol.SymbolUtilities;
|
import ghidra.program.model.symbol.SymbolUtilities;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
|
||||||
|
|
||||||
public class ParameterDefinitionImpl implements ParameterDefinition {
|
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.
|
* @param ordinal the index of this parameter within the function signature.
|
||||||
*/
|
*/
|
||||||
protected ParameterDefinitionImpl(String name, DataType dataType, String comment, int ordinal) {
|
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.name = name;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
this.ordinal = ordinal;
|
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) {
|
if (dataType == null) {
|
||||||
dataType = DataType.DEFAULT;
|
dataType = DataType.DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -65,21 +64,23 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
||||||
}
|
}
|
||||||
else if (dataType instanceof Dynamic || dataType instanceof FactoryDataType) {
|
else if (dataType instanceof Dynamic || dataType instanceof FactoryDataType) {
|
||||||
throw new IllegalArgumentException(
|
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.getName());
|
||||||
}
|
}
|
||||||
dataType = dataType.clone(dtMgr != null ? dtMgr : dataType.getDataTypeManager());
|
dataType = dataType.clone(dtMgr != null ? dtMgr : dataType.getDataTypeManager());
|
||||||
if (!dataType.isDynamicallySized() && dataType.getLength() < 0) {
|
if (!dataType.isDynamicallySized() && dataType.getLength() < 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(kind +
|
||||||
"Parameter must be specified with fixed-length data type: " + dataType.getName());
|
" type must be specified with fixed-length data type: " + dataType.getName());
|
||||||
}
|
}
|
||||||
if (dataType instanceof VoidDataType) {
|
if (dataType instanceof VoidDataType) {
|
||||||
throw new IllegalArgumentException(
|
if (!isReturn) {
|
||||||
"Parameter may not specify the void datatype - empty parameter list should be used");
|
throw new IllegalArgumentException(
|
||||||
|
"Parameter type may not specify the void datatype - empty parameter list should be used");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(dataType instanceof Composite) && dataType.getLength() == 0) {
|
else if (!(dataType instanceof Composite) && dataType.getLength() == 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(kind +
|
||||||
"Parameter must be specified with fixed-length data type: " + dataType.getName());
|
" type must be specified with fixed-length data type: " + dataType.getName());
|
||||||
}
|
}
|
||||||
return dataType;
|
return dataType;
|
||||||
}
|
}
|
||||||
|
@ -129,8 +130,8 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDataType(DataType type) throws InvalidInputException {
|
public void setDataType(DataType type) {
|
||||||
this.dataType = checkDataType(type, dataType.getDataTypeManager());
|
this.dataType = checkDataType(type, dataType.getDataTypeManager(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -141,31 +142,6 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
|
||||||
this.name = name;
|
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
|
@Override
|
||||||
public boolean isEquivalent(Variable variable) {
|
public boolean isEquivalent(Variable variable) {
|
||||||
if (variable == null) {
|
if (variable == null) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue