mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Refactor SegmentedAddress preparing for protected mode
This commit is contained in:
parent
90f832bf1d
commit
cabe66e282
2 changed files with 113 additions and 208 deletions
|
@ -21,70 +21,48 @@ package ghidra.program.model.address;
|
||||||
*/
|
*/
|
||||||
public class SegmentedAddress extends GenericAddress {
|
public class SegmentedAddress extends GenericAddress {
|
||||||
|
|
||||||
private static final long serialVersionUID = 0;
|
|
||||||
public static final int OFFSET_SIZE = 16;
|
|
||||||
public static final int SEGMENT_SIZE = 16;
|
|
||||||
|
|
||||||
private final SegmentedAddressSpace addrSpace;
|
|
||||||
private final int segment;
|
private final int segment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for SegmentedAddress.
|
* Constructor for SegmentedAddress.
|
||||||
* Offset is not validated against address space.
|
* Offset is not validated against address space.
|
||||||
* @param addrSpace address space for this address
|
* @param addrSpace is the address space for this address
|
||||||
* @param offset offset into the space
|
* @param flat is the flat offset into the space
|
||||||
*/
|
*/
|
||||||
SegmentedAddress(long offset, SegmentedAddressSpace addrSpace) {
|
SegmentedAddress(long flat, SegmentedAddressSpace addrSpace) {
|
||||||
super(adjustOffset(offset), addrSpace);
|
super(adjustOffset(flat, addrSpace), addrSpace);
|
||||||
this.addrSpace = addrSpace;
|
segment = addrSpace.getSegmentFromFlat(flat);
|
||||||
if (offset > 0xFFFFF) {
|
|
||||||
this.segment = 0xFFFF;
|
|
||||||
} else {
|
|
||||||
this.segment = (int) ((offset >> 4) & 0xf000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for SegmentedAddress.
|
* Constructor for SegmentedAddress.
|
||||||
* @param addrSpace address space for this address
|
* @param addrSpace is the address space for this address
|
||||||
* @param segmentOffset offset into the segment
|
* @param segment is the segment number
|
||||||
* @param overlayId overlay number
|
* @param segmentOffset is the offset into the segment
|
||||||
* @param segment segment number
|
* @throws AddressOutOfBoundsException if the address does not fit in the space
|
||||||
*/
|
*/
|
||||||
SegmentedAddress(SegmentedAddressSpace addrSpace, int segment, int segmentOffset)
|
SegmentedAddress(SegmentedAddressSpace addrSpace, int segment, int segmentOffset)
|
||||||
throws AddressOutOfBoundsException {
|
throws AddressOutOfBoundsException {
|
||||||
super(addrSpace, (segment << 4) + segmentOffset);
|
super(addrSpace, addrSpace.getFlatOffset(segment, segmentOffset));
|
||||||
this.addrSpace = addrSpace;
|
this.segment = segment;
|
||||||
if (offset > 0xFFFFF) {
|
|
||||||
this.segment = 0xFFFF;
|
|
||||||
} else {
|
|
||||||
this.segment = segment;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for SegmentedAddress.
|
* Constructor for SegmentedAddress.
|
||||||
* @param addrSpace address space for this address
|
* @param addrSpace address space for this address
|
||||||
* @param offset offset into the space
|
* @param flat is the flat offset into the space
|
||||||
|
* @throws AddressOutOfBoundsException if the flat address does not fit in the space
|
||||||
*/
|
*/
|
||||||
SegmentedAddress(SegmentedAddressSpace addrSpace, long offset)
|
SegmentedAddress(SegmentedAddressSpace addrSpace, long flat)
|
||||||
throws AddressOutOfBoundsException {
|
throws AddressOutOfBoundsException {
|
||||||
super(addrSpace, adjustOffset(offset));
|
super(addrSpace, adjustOffset(flat, addrSpace));
|
||||||
this.addrSpace = addrSpace;
|
segment = addrSpace.getSegmentFromFlat(flat);
|
||||||
if (offset > 0xFFFFF) {
|
|
||||||
this.segment = 0xFFFF;
|
|
||||||
} else {
|
|
||||||
this.segment = (int) ((offset >> 4) & 0xf000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long adjustOffset(long offset) {
|
private static long adjustOffset(long flat, SegmentedAddressSpace addrSpace) {
|
||||||
// Decompiler treats segmented space as a 32-bit space and may produce an address offset
|
int seg = addrSpace.getSegmentFromFlat(flat);
|
||||||
// of 0xffffffff for a first use offset (= 0 minus 1).
|
long offset = addrSpace.getOffsetFromFlat(flat);
|
||||||
if (offset == 0x0ffffffffL) {
|
return addrSpace.getFlatOffset(seg, offset);
|
||||||
offset = 0x0fffffL;
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,25 +75,24 @@ public class SegmentedAddress extends GenericAddress {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the offset within the segment.
|
* Returns the offset within the segment.
|
||||||
|
* @return the offset value
|
||||||
*/
|
*/
|
||||||
public int getSegmentOffset() {
|
public int getSegmentOffset() {
|
||||||
return (int) (offset - (segment << 4));
|
return (int) ((SegmentedAddressSpace) addrSpace).getOffsetFromFlat(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new address that is equivalent to this address using
|
* Returns a new address that is equivalent to this address using
|
||||||
* the given segment number.
|
* the given segment number.
|
||||||
* @param seg the seqment value to normalize to.
|
* @param seg the seqment value to normalize to.
|
||||||
|
* @return the new address
|
||||||
*/
|
*/
|
||||||
public SegmentedAddress normalize(int seg) {
|
public SegmentedAddress normalize(int seg) {
|
||||||
if ((seg << 4) > offset) {
|
SegmentedAddress res = ((SegmentedAddressSpace) addrSpace).getAddressInSegment(offset, seg);
|
||||||
|
if (res == null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
int off = (int) (offset - (seg << 4));
|
return res;
|
||||||
if (off > 0xffff) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
return new SegmentedAddress(addrSpace, seg, off);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,8 +101,12 @@ public class SegmentedAddress extends GenericAddress {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Address getNewAddress(long byteOffset) {
|
public Address getNewAddress(long byteOffset) {
|
||||||
SegmentedAddress segAddr = addrSpace.getAddress(byteOffset);
|
SegmentedAddress res =
|
||||||
return segAddr.normalize(segment);
|
((SegmentedAddressSpace) addrSpace).getAddressInSegment(byteOffset, segment);
|
||||||
|
if (res == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,33 +155,4 @@ public class SegmentedAddress extends GenericAddress {
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.address.GenericAddress#next()
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address next() {
|
|
||||||
if ((offset & SegmentedAddressSpace.MASK) == SegmentedAddressSpace.MASK) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
long newOffset = (offset + 1) & SegmentedAddressSpace.MASK;
|
|
||||||
return new SegmentedAddress(addrSpace, newOffset).normalize(segment);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.address.GenericAddress#previous()
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address previous() {
|
|
||||||
if ((offset & SegmentedAddressSpace.MASK) == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
long newOffset = (offset - 1) & SegmentedAddressSpace.MASK;
|
|
||||||
return new SegmentedAddress(addrSpace, newOffset).normalize(segment);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,16 +26,10 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
|
|
||||||
private final static int SIZE = 21;
|
private final static int SIZE = 21;
|
||||||
|
|
||||||
//private final static int SEGMENT_OFFSET_MASK = 0xffff;
|
|
||||||
//final static long MASK = (1L << SIZE) - 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new Segmented AddressSpace.
|
* Constructs a new Segmented AddressSpace.
|
||||||
*
|
* @param name is the name of the space
|
||||||
* @param name
|
* @param unique is the unique id for the space.
|
||||||
* the name of the space
|
|
||||||
* @param unique
|
|
||||||
* the unique id for the space.
|
|
||||||
*/
|
*/
|
||||||
public SegmentedAddressSpace(String name, int unique) {
|
public SegmentedAddressSpace(String name, int unique) {
|
||||||
super(name, SIZE, TYPE_RAM, unique);
|
super(name, SIZE, TYPE_RAM, unique);
|
||||||
|
@ -44,6 +38,65 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
maxAddress = getUncheckedAddress(maxOffset);
|
maxAddress = getUncheckedAddress(maxOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a 16-bit segment and an offset, produce the flat address offset
|
||||||
|
* @param segment is the segment value
|
||||||
|
* @param offset is the 16-bit offset into the segment
|
||||||
|
* @return the encoded flat offset
|
||||||
|
*/
|
||||||
|
protected long getFlatOffset(int segment, long offset) {
|
||||||
|
long res = segment;
|
||||||
|
res <<= 4;
|
||||||
|
res += offset;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a flat address offset, extract the 16-bit segment portion
|
||||||
|
* @param flat is the flat offset
|
||||||
|
* @return the segment value
|
||||||
|
*/
|
||||||
|
protected int getSegmentFromFlat(long flat) {
|
||||||
|
if (flat > 0xFFFFFL) {
|
||||||
|
return 0xFFFF;
|
||||||
|
}
|
||||||
|
return (int) ((flat >> 4) & 0xF000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a flat address offset, extract the offset portion
|
||||||
|
* @param flat is the flat offset
|
||||||
|
* @return the offset value
|
||||||
|
*/
|
||||||
|
protected long getOffsetFromFlat(long flat) {
|
||||||
|
if (flat > 0xFFFFFL) {
|
||||||
|
return flat - 0xFFFF0;
|
||||||
|
}
|
||||||
|
return flat & 0xFFFFL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a flat address offset and a preferred segment, try
|
||||||
|
* to create an address that maps to the offset and is in the segment. For
|
||||||
|
* architectures like x86 real-mode, multiple address encodings can map to
|
||||||
|
* the same flat address offset. This method tries to select between the different
|
||||||
|
* encodings. If the flat offset cannot be encoded with the preferred segment,
|
||||||
|
* null is returned.
|
||||||
|
*
|
||||||
|
* @param flat is the flat offset
|
||||||
|
* @param preferredSegment is the 16-bit preferred segment value
|
||||||
|
* @return the segment encoded address or null
|
||||||
|
*/
|
||||||
|
protected SegmentedAddress getAddressInSegment(long flat, int preferredSegment) {
|
||||||
|
if ((preferredSegment << 4) <= flat) {
|
||||||
|
int off = (int) (flat - (preferredSegment << 4));
|
||||||
|
if (off <= 0xffff) {
|
||||||
|
return new SegmentedAddress(this, preferredSegment, off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @see ghidra.program.model.address.AddressSpace#getAddress(java.lang.String)
|
* @see ghidra.program.model.address.AddressSpace#getAddress(java.lang.String)
|
||||||
|
@ -98,62 +151,16 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
long off = addr.getOffset() - displacement;
|
long off = addr.getOffset() - displacement;
|
||||||
if (off >= 0) {
|
if (off >= 0) {
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
SegmentedAddress saddr = (SegmentedAddress) addr;
|
||||||
return new SegmentedAddress(this, off).normalize(saddr.getSegment());
|
Address resaddr = getAddressInSegment(off, saddr.getSegment());
|
||||||
|
if (resaddr == null) { // Could not map into desired segment
|
||||||
|
resaddr = new SegmentedAddress(this, off); // just use default
|
||||||
|
}
|
||||||
|
return resaddr;
|
||||||
}
|
}
|
||||||
throw new AddressOutOfBoundsException(
|
throw new AddressOutOfBoundsException(
|
||||||
"Address Overflow in subtract: " + addr + " + " + displacement);
|
"Address Overflow in subtract: " + addr + " + " + displacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see ghidra.program.model.address.AddressSpace#subtractWrap(ghidra.program.model.address.Address,
|
|
||||||
* long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address subtractWrap(Address addr, long displacement) {
|
|
||||||
|
|
||||||
testAddressSpace(addr);
|
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
|
||||||
|
|
||||||
int segOffset = (int) ((saddr.getSegmentOffset() - displacement) & SEGMENT_OFFSET_MASK);
|
|
||||||
return new SegmentedAddress(this, saddr.getSegment(), segOffset);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.address.AbstractAddressSpace#subtractWrapSpace(ghidra.program.model.address.Address, long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address subtractWrapSpace(Address addr, long displacement) {
|
|
||||||
testAddressSpace(addr);
|
|
||||||
return new SegmentedAddress(this, (addr.getOffset() - displacement) & MASK);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see ghidra.program.model.address.AddressSpace#subtractNoWrap(ghidra.program.model.address.Address,
|
|
||||||
* long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address subtractNoWrap(Address addr, long displacement) throws AddressOverflowException {
|
|
||||||
|
|
||||||
testAddressSpace(addr);
|
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
|
||||||
|
|
||||||
long off = addr.getOffset() - displacement;
|
|
||||||
if ((off & MASK) != off) {
|
|
||||||
throw new AddressOverflowException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SegmentedAddress(this, off).normalize(saddr.getSegment());
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @see ghidra.program.model.address.AddressSpace#add(ghidra.program.model.address.Address,
|
* @see ghidra.program.model.address.AddressSpace#add(ghidra.program.model.address.Address,
|
||||||
|
@ -175,110 +182,56 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
//if ((off & MASK) == off) {
|
//if ((off & MASK) == off) {
|
||||||
if (off >= 0 && off <= maxOffset) {
|
if (off >= 0 && off <= maxOffset) {
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
SegmentedAddress saddr = (SegmentedAddress) addr;
|
||||||
return new SegmentedAddress(this, off).normalize(saddr.getSegment());
|
Address resaddr = getAddressInSegment(off, saddr.getSegment());
|
||||||
|
if (resaddr == null) { // Could not map into desired segment
|
||||||
|
resaddr = new SegmentedAddress(this, off); // just use default
|
||||||
|
}
|
||||||
|
return resaddr;
|
||||||
}
|
}
|
||||||
throw new AddressOutOfBoundsException(
|
throw new AddressOutOfBoundsException(
|
||||||
"Address Overflow in add: " + addr + " + " + displacement);
|
"Address Overflow in add: " + addr + " + " + displacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see ghidra.program.model.address.AddressSpace#addWrap(ghidra.program.model.address.Address,
|
|
||||||
* long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address addWrap(Address addr, long displacement) {
|
|
||||||
testAddressSpace(addr);
|
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
|
||||||
|
|
||||||
int segOffset = (int) ((saddr.getSegmentOffset() + displacement) & SEGMENT_OFFSET_MASK);
|
|
||||||
return new SegmentedAddress(this, saddr.getSegment(), segOffset);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.program.model.address.AddressSpace#addWrapSpace(ghidra.program.model.address.Address,
|
|
||||||
* long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address addWrapSpace(Address addr, long displacement) {
|
|
||||||
testAddressSpace(addr);
|
|
||||||
return new SegmentedAddress(this, (addr.getOffset() + displacement) & MASK);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see ghidra.program.model.address.AddressSpace#addNoWrap(ghidra.program.model.address.Address,
|
|
||||||
* long)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public Address addNoWrap(Address addr, long displacement) throws AddressOverflowException {
|
|
||||||
|
|
||||||
SegmentedAddress saddr = (SegmentedAddress) addr;
|
|
||||||
testAddressSpace(addr);
|
|
||||||
|
|
||||||
long off = addr.getOffset() + displacement;
|
|
||||||
if ((off & MASK) != off) {
|
|
||||||
throw new AddressOverflowException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SegmentedAddress(this, off).normalize(saddr.getSegment());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private long parseString(String addr) {
|
private long parseString(String addr) {
|
||||||
if (addr.startsWith("0x") || addr.startsWith("0X")) {
|
if (addr.startsWith("0x") || addr.startsWith("0X")) {
|
||||||
return NumericUtilities.parseHexLong(addr.substring(2));
|
return NumericUtilities.parseHexLong(addr.substring(2));
|
||||||
}
|
}
|
||||||
return NumericUtilities.parseHexLong(addr);
|
return NumericUtilities.parseHexLong(addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SegmentedAddress parseNonSegmented(String offStr) throws AddressFormatException {
|
private SegmentedAddress parseNonSegmented(String offStr) throws AddressFormatException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long off = (int) parseString(offStr);
|
long off = (int) parseString(offStr);
|
||||||
if (off < 0 || off > 0xfffff) {
|
|
||||||
throw new AddressFormatException("Offset is outside the range 0 to 0xfffff");
|
|
||||||
}
|
|
||||||
return new SegmentedAddress(this, off);
|
return new SegmentedAddress(this, off);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
throw new AddressFormatException("Cannot parse (" + offStr + ") as a number.");
|
throw new AddressFormatException("Cannot parse (" + offStr + ") as a number.");
|
||||||
}
|
}
|
||||||
|
catch (AddressOutOfBoundsException e) {
|
||||||
|
throw new AddressFormatException(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SegmentedAddress parseSegmented(String segStr, String offStr)
|
private SegmentedAddress parseSegmented(String segStr, String offStr)
|
||||||
throws AddressFormatException {
|
throws AddressFormatException {
|
||||||
int seg = -1;
|
int seg = -1;
|
||||||
|
int off = -1;
|
||||||
try {
|
try {
|
||||||
seg = (int) parseString(segStr);
|
seg = (int) parseString(segStr);
|
||||||
|
off = (int) parseString(offStr);
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
return null;
|
throw new AddressFormatException(
|
||||||
}
|
"Cannot parse (" + segStr + ':' + offStr + ") as a number.");
|
||||||
if (seg < 0 || seg > 0xffff) {
|
|
||||||
throw new AddressFormatException("Segment is outside the range 0 to 0xffff");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int off = (int) parseString(offStr);
|
return getAddress(seg, off);
|
||||||
if (off < 0 || off > 0xffff) {
|
|
||||||
throw new AddressFormatException("Offset is outside the range 0 to 0xffff");
|
|
||||||
}
|
|
||||||
return new SegmentedAddress(this, seg, off);
|
|
||||||
}
|
}
|
||||||
catch (AddressOutOfBoundsException e) {
|
catch (AddressOutOfBoundsException e) {
|
||||||
throw new AddressFormatException(e.getMessage());
|
throw new AddressFormatException(e.getMessage());
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
|
||||||
throw new AddressFormatException("Cannot parse (" + offStr + ") as a number.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,8 +268,8 @@ public class SegmentedAddressSpace extends GenericAddressSpace {
|
||||||
if (segmentOffset > 0xffff) {
|
if (segmentOffset > 0xffff) {
|
||||||
throw new AddressOutOfBoundsException("Offset is too large.");
|
throw new AddressOutOfBoundsException("Offset is too large.");
|
||||||
}
|
}
|
||||||
if ((segment << 4) + segmentOffset > maxOffset) {
|
if (segment > 0xffff) {
|
||||||
throw new AddressOutOfBoundsException("Segmented address is too large.");
|
throw new AddressOutOfBoundsException("Segment is too large.");
|
||||||
}
|
}
|
||||||
return new SegmentedAddress(this, segment, segmentOffset);
|
return new SegmentedAddress(this, segment, segmentOffset);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue