diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java index 658a0ad541..3a09823d3b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java @@ -42,11 +42,10 @@ public class SetRegisterCmd implements Command { * A null value indicates that no value should be associated over the range. */ public SetRegisterCmd(Register register, Address start, Address end, BigInteger value) { - if (start.getAddressSpace() != end.getAddressSpace()) { + if (!start.getAddressSpace().equals(end.getAddressSpace())) { throw new IllegalArgumentException( - "start and end address must be in the same address space"); + "start and end address must be within the same address space"); } - this.register = register; this.start = start; this.end = end; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/RegisterMergeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/RegisterMergeManager.java index de48b75199..ed3514d727 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/RegisterMergeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/RegisterMergeManager.java @@ -32,6 +32,7 @@ import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.program.model.mem.Memory; import ghidra.program.util.*; +import ghidra.util.exception.AssertException; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -98,6 +99,17 @@ class RegisterMergeManager implements ListingMergeConstants { * @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. */ + /** + * Creates a RegisterMergeManager. + * @param registerName + * @param mergeManager + * @param resultPgm the program to be updated with the result of the merge. + * @param originalPgm the program that was checked out. + * @param latestPgm the latest checked-in version of the program. + * @param myPgm the program requesting to be checked in. + * @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. + */ RegisterMergeManager(String registerName, ProgramMultiUserMergeManager mergeManager, Program resultPgm, Program originalPgm, Program latestPgm, Program myPgm, ProgramChangeSet latestChanges, ProgramChangeSet myChanges) { @@ -123,10 +135,7 @@ class RegisterMergeManager implements ListingMergeConstants { } } - /* (non-Javadoc) - * @see ghidra.app.merge.MergeResolver#apply() - */ - public void apply() { + void apply() { conflictOption = conflictPanel.getSelectedOptions(); // If the "Use For All" check box is selected @@ -138,27 +147,10 @@ class RegisterMergeManager implements ListingMergeConstants { merge(min, max, resultReg); } - /* (non-Javadoc) - * @see ghidra.app.merge.MergeResolver#cancel() - */ - public void cancel() { + void cancel() { conflictOption = CANCELED; } - /* (non-Javadoc) - * @see ghidra.app.merge.MergeResolver#getDescription() - */ - public String getDescription() { - return "Merge Register"; - } - - /* (non-Javadoc) - * @see ghidra.app.merge.MergeResolver#getName() - */ - public String getName() { - return "Register Merger"; - } - /** * * @param monitor @@ -183,54 +175,6 @@ class RegisterMergeManager implements ListingMergeConstants { autoSet = setToCheck.subtract(conflictSet); } - private Address getCompatibleAddress(AddressFactory addrFactory, Address otherAddr) { - AddressSpace space = otherAddr.getAddressSpace(); - AddressSpace s = addrFactory.getAddressSpace(space.getName()); - if (!space.equals(s)) { - throw new IllegalArgumentException("Invalid address for target program: " + otherAddr); - } - return s.getAddress(otherAddr.getOffset()); - } - - private void setValue(Program p, Register register, Address start, Address end, - BigInteger value) { - - // Since all program must have the same set of AddressSpaces, we can assume that addresses - // from one program will be valid within another. However, in order to comply with - // address space instance restrictions we must ensure that addresses used for applying - // register context correspond to the target program. - - ProgramContext ctx = p.getProgramContext(); - AddressFactory addrFactory = p.getAddressFactory(); - - try { - ctx.setValue(register, getCompatibleAddress(addrFactory, start), - getCompatibleAddress(addrFactory, end), value); - } - catch (ContextChangeException e) { - // ignore since processor context-register is not handled by this merge manager - } - } - - private void removeValue(Program p, Register register, Address start, Address end) { - - // Since all program must have the same set of AddressSpaces, we can assume that addresses - // from one program will be valid within another. However, in order to comply with - // address space instance restrictions we must ensure that addresses used for applying - // register context correspond to the target program. - - ProgramContext ctx = p.getProgramContext(); - AddressFactory addrFactory = p.getAddressFactory(); - - try { - ctx.remove(getCompatibleAddress(addrFactory, start), - getCompatibleAddress(addrFactory, end), register); - } - catch (ContextChangeException e) { - // ignore since processor context-register is not handled by this merge manager - } - } - /** * Merges all the register values for the named register being managed by this merge manager. * @param monitor the monitor that provides feedback to the user. @@ -246,17 +190,24 @@ class RegisterMergeManager implements ListingMergeConstants { // resulting program has the mem addresses but the latest doesn't. AddressRangeIterator arIter = autoSet.getAddressRanges(); while (arIter.hasNext() && !monitor.isCancelled()) { - AddressRange range = arIter.next(); - Address rangeMin = range.getMinAddress(); - Address rangeMax = range.getMaxAddress(); - removeValue(resultPgm, resultReg, rangeMin, rangeMax); - AddressRangeIterator it = - myContext.getRegisterValueAddressRanges(resultReg, rangeMin, rangeMax); - while (it.hasNext()) { - AddressRange valueRange = it.next(); - BigInteger value = myContext.getValue(resultReg, valueRange.getMinAddress(), false); - setValue(resultPgm, resultReg, valueRange.getMinAddress(), - valueRange.getMaxAddress(), value); + try { + AddressRange range = arIter.next(); + Address rangeMin = range.getMinAddress(); + Address rangeMax = range.getMaxAddress(); + resultContext.remove(rangeMin, rangeMax, resultReg); + AddressRangeIterator it = + myContext.getRegisterValueAddressRanges(resultReg, rangeMin, rangeMax); + while (it.hasNext()) { + AddressRange valueRange = it.next(); + BigInteger value = + myContext.getValue(resultReg, valueRange.getMinAddress(), false); + resultContext.setValue(resultReg, valueRange.getMinAddress(), + valueRange.getMaxAddress(), value); + } + } + catch (ContextChangeException e) { + // processor context-register is not handled here and should not occur + throw new AssertException(e); } } @@ -334,7 +285,13 @@ class RegisterMergeManager implements ListingMergeConstants { */ private void merge(Address minAddress, Address maxAddress, Register resultRegister, BigInteger myValue) { - setValue(resultPgm, resultRegister, minAddress, maxAddress, myValue); + try { + resultContext.setValue(resultRegister, minAddress, maxAddress, myValue); + } + catch (ContextChangeException e) { + // processor context-register is not handled here and should not occur + throw new AssertException(e); + } } /** diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionManagerDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionManagerDB.java index 95a2b6def9..71f0b03a10 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionManagerDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionManagerDB.java @@ -220,10 +220,13 @@ public class FunctionManagerDB implements FunctionManager { } } - static void checkSingleAddressSpaceOnly(AddressSetView set) { - if (set.getMinAddress().getAddressSpace() != set.getMaxAddress().getAddressSpace()) { - throw new IllegalArgumentException( - "Function body must contain single address space only"); + static void checkSingleAddressSpaceOnly(AddressSetView set) throws IllegalArgumentException { + AddressSpace addressSpace = set.getMinAddress().getAddressSpace(); + for (AddressRange range : set.getAddressRanges()) { + if (range.getMinAddress().getAddressSpace() != addressSpace) { + throw new IllegalArgumentException( + "Function body must contain single address space only"); + } } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractStoredProgramContext.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractStoredProgramContext.java index 7d309b88bb..607641a4ee 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractStoredProgramContext.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/util/AbstractStoredProgramContext.java @@ -247,9 +247,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex @Override public void remove(Address start, Address end, Register register) throws ContextChangeException { - if (start.getAddressSpace() != end.getAddressSpace()) { + if (!start.getAddressSpace().equals(end.getAddressSpace())) { throw new IllegalArgumentException( - "start and end address must refer to the same address space instance"); + "start and end address must be within the same address space"); } RegisterValueStore values = registerValueMap.get(register.getBaseRegister()); if (values != null) { @@ -259,8 +259,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex } // public void removeDefault(Address start, Address end, Register register) { -// if (start.getAddressSpace() != end.getAddressSpace()) { -// throw new IllegalArgumentException("start and end address must refer to the same address space instance"); +// if (!start.getAddressSpace().equals(end.getAddressSpace())) { +// throw new IllegalArgumentException( +// "start and end address must be within the same address space"); // } // invalidateCache(); // RegisterValueStore values = defaultRegisterValueMap.get(register.getBaseRegister()); @@ -272,9 +273,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex @Override public void setValue(Register register, Address start, Address end, BigInteger value) throws ContextChangeException { - if (start.getAddressSpace() != end.getAddressSpace()) { + if (!start.getAddressSpace().equals(end.getAddressSpace())) { throw new IllegalArgumentException( - "start and end address must refer to the same address space instance"); + "start and end address must be within the same address space"); } if (value == null) { remove(start, end, register); @@ -285,9 +286,9 @@ abstract public class AbstractStoredProgramContext extends AbstractProgramContex @Override public void setDefaultValue(RegisterValue registerValue, Address start, Address end) { - if (start.getAddressSpace() != end.getAddressSpace()) { + if (!start.getAddressSpace().equals(end.getAddressSpace())) { throw new IllegalArgumentException( - "start and end address must refer to the same address space instance"); + "start and end address must be within the same address space"); } Register baseRegister = registerValue.getRegister().getBaseRegister(); RegisterValueStore store = defaultRegisterValueMap.get(baseRegister);