From 62dc049cb0347675b12e6437362bce1c7e837ba7 Mon Sep 17 00:00:00 2001 From: ghidragon <106987263+ghidragon@users.noreply.github.com> Date: Tue, 5 May 2026 13:53:43 -0400 Subject: [PATCH] added subtractNoWrap(BigInteger) --- .../model/address/AbstractAddressSpace.java | 20 +++++++++++++++++++ .../ghidra/program/model/address/Address.java | 5 +++-- .../program/model/address/AddressSpace.java | 11 ++++++++++ .../program/model/address/GenericAddress.java | 7 +++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java index ba4fe55969..f57ec83561 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AbstractAddressSpace.java @@ -414,6 +414,26 @@ abstract class AbstractAddressSpace implements AddressSpace { long resultOffset = NumericUtilities.bigIntegerToUnsignedLong(newOffset); return getUncheckedAddress(resultOffset); } + @Override + public Address subtractNoWrap(GenericAddress addr, BigInteger displacement) + throws AddressOverflowException { + + if (displacement.equals(BigInteger.ZERO)) { + return addr; + } + testAddressSpace(addr); + BigInteger addrOff = addr.getOffsetAsBigInteger(); + BigInteger maxOff = maxAddress.getOffsetAsBigInteger(); + BigInteger minOff = minAddress.getOffsetAsBigInteger(); + BigInteger newOffset = addrOff.subtract(displacement); + if (newOffset.compareTo(minOff) < 0 || newOffset.compareTo(maxOff) > 0) { + throw new AddressOverflowException( + "Address Overflow in add: " + addr + " + " + displacement); + } + + long resultOffset = NumericUtilities.bigIntegerToUnsignedLong(newOffset); + return getUncheckedAddress(resultOffset); + } @Override public Address add(Address addr, long displacement) throws AddressOutOfBoundsException { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/Address.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/Address.java index ef4eaec462..5fe08eca94 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/Address.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/Address.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -254,6 +254,7 @@ public interface Address extends Comparable
{ public Address addNoWrap(long displacement) throws AddressOverflowException; public Address addNoWrap(BigInteger displacement) throws AddressOverflowException; + public Address subtractNoWrap(BigInteger displacement) throws AddressOverflowException; /** * Creates a new address (possibly in a new space) by adding the displacement to this address. diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressSpace.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressSpace.java index b828518170..bef7522f99 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressSpace.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressSpace.java @@ -363,6 +363,17 @@ public interface AddressSpace extends Comparable { public Address addNoWrap(GenericAddress addr, BigInteger displacement) throws AddressOverflowException; + /** + * Creates a new address by subtracting the displacement to the given address. The + * new address will NOT wrap! + * @param addr the original address. + * @param displacement the displacement to subtract. + * @return The new address created by subtracting the displacement to addr.offset. + * @throws AddressOverflowException if the addition would cause a wrap, + */ + public Address subtractNoWrap(GenericAddress addr, BigInteger displacement) + throws AddressOverflowException; + /** * Creates a new address (possibly in a new space) by adding the given * displacement from the given address. diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/GenericAddress.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/GenericAddress.java index c5fe598ead..f2de13f3cd 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/GenericAddress.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/GenericAddress.java @@ -176,6 +176,13 @@ public class GenericAddress implements Address { } return addrSpace.addNoWrap(this, displacement); } + @Override + public Address subtractNoWrap(BigInteger displacement) throws AddressOverflowException { + if (displacement.equals(BigInteger.ZERO)) { + return this; + } + return addrSpace.subtractNoWrap(this, displacement); + } @Override public Address add(long displacement) {