diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh index 11fb1cd668..aa1cb6ae2a 100644 --- a/src/base/addr_range.hh +++ b/src/base/addr_range.hh @@ -455,7 +455,18 @@ 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 r will be a subset only if its _end + // also wraps around. + return _start >= r._start && r._end == 0; + } 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..f1a454ff5f 100644 --- a/src/base/addr_range.test.cc +++ b/src/base/addr_range.test.cc @@ -1544,6 +1544,19 @@ 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)); +} /* * InterleavingRanges: * The exclude method does not support interleaving ranges