diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh index 11fb1cd668..d49ebf49b6 100644 --- a/src/base/addr_range.hh +++ b/src/base/addr_range.hh @@ -455,7 +455,25 @@ class AddrRange return r.contains(_start) && r.contains(_end - 1) && size() <= r.granularity(); } else { - return _start >= r._start && _end <= r._end; + + if (_end <= _start){ + // Special case: if our range wraps around that is + // _end is 2^64 so it wraps to 0. + // In this case we will be a subset only if r._end + // also wraps around. + return _start >= r._start && r._end == 0; + } else if (r._end <= r._start){ + // Special case: if r wraps around that is + // r._end is 2^64 so it wraps to 0. + // In this case we will be a subset only if our _start + // is within r._start/ _end does not matter + // because r wraps around. + return _start >= r._start; + } else { + // Normal case: Check if our range is completely within 'r'. + return _start >= r._start && _end <= r._end; + } + } } diff --git a/src/base/addr_range.test.cc b/src/base/addr_range.test.cc index 1e861544ff..eb7bed971a 100644 --- a/src/base/addr_range.test.cc +++ b/src/base/addr_range.test.cc @@ -1544,6 +1544,36 @@ TEST(AddrRangeTest, SubtractionAssignmentOfRangeListFromRangeList) expected_range3, expected_range4)); } +TEST(AddrRangeTest, isNotSubsetLastByte) +{ + /* An issue raised in https://github.com/gem5/gem5/issues/240 where if an + * address range ends at the last byte of a 64 bit address space, it will + * be considered a subset of any other address range that starts at the + * first byte of the range. + */ + + AddrRange first_four_bytes = RangeSize(0x0, 4); + AddrRange last_four_bytes = RangeSize(0xfffffffffffffffc, 4); + + EXPECT_FALSE(last_four_bytes.isSubset(first_four_bytes)); +} + +TEST(AddrRangeTest, isSubsetLastByte) +{ + /* An issue raised in https://github.com/gem5/gem5/issues/240 where if an + * address range ends at the last byte of a 64 bit address space, it will + * be considered a subset of any other address range that starts at the + * first byte of the range. + * + * This test checks it subset works correctly when the range is the last + * byte of the address space. + */ + AddrRange last_four_bytes = RangeSize(0xfffffffffffffffc, 4); + AddrRange not_wrapped_last_bytes = RangeSize(0xfffffffffffffffc, 3); + + EXPECT_TRUE(not_wrapped_last_bytes.isSubset(last_four_bytes)); +} + /* * InterleavingRanges: * The exclude method does not support interleaving ranges