Address Range
Helper Class For Handling Address Ranges.
Classes:
| Name | Description |
|---|---|
AddrRange |
Address range starting at |
IntersectError |
AddrRange Intersection Error. |
AddrRange
Bases: mementos
Address range starting at baseaddr with size in bytes.
Methods:
| Name | Description |
|---|---|
__init__ |
Address range starting at |
__str__ |
Return String representation. |
__repr__ |
Return extended representation. |
__contains__ |
Check whether |
__iter__ |
Iterate over all addresses inside range. |
is_overlapping |
Return |
get_intersect |
Return intersection of self and |
get_difference |
Get difference of |
Attributes:
| Name | Type | Description |
|---|---|---|
endaddr |
Hex
|
Hexvalue of end address of range. |
nextaddr |
Hex
|
Hexvalue of first address after range. |
__init__
Example:
>>> a = AddrRange(0x1000, 0x100)
>>> a
AddrRange(0x1000, '256 bytes')
>>> b = AddrRange(0x1000, 0x100, item='B')
>>> b
AddrRange('B', 0x1000, '256 bytes')
>>> c = AddrRange(0x1000, 0x100, is_sub=True)
>>> c
AddrRange(0x1000, '256 bytes', is_sub=True)
>>> d = AddrRange(0x1000, 0x100, item='D', is_sub=True)
>>> d
AddrRange('D', 0x1000, '256 bytes', is_sub=True)
The addrwidth just formats the address representation:
>>> a = AddrRange(0x1000, 0x100, addrwidth=32)
>>> a
AddrRange(0x00001000, '256 bytes', addrwidth=32)
>>> str(a)
'0x00001000-0x000010FF(256 bytes)'
>>> str(a.nextaddr)
'0x00001100'
Address ranges can be compared:
>>> AddrRange(0x1000, 0x100) == AddrRange(0x1000, 0x100)
True
>>> AddrRange(0x1000, 0x100) == AddrRange(0x1000, 0x200)
False
Comparing an AddrRange against another type just returns False:
>>> AddrRange(0x1000, 0x100) == 42
False
Addresses can be checked whether they lie within the range:
>>> 0x1008 in a
True
>>> 0x1400 in a
False
Address ranges can be iterated over:
>>> for i in AddrRange(0x200, 6):
... print(i)
512
513
514
515
516
517
is_overlapping
Return True if other overlaps.
Example:
>>> AddrRange(0x1000, '4 KB').is_overlapping(AddrRange(0x3000, '4 KB'))
False
>>> AddrRange(0x1000, '4 KB').is_overlapping(AddrRange(0x2000, '4 KB'))
False
>>> AddrRange(0x1000, '4 KB').is_overlapping(AddrRange(0x2000, 0x1))
False
>>> AddrRange(0x1000, '4 KB').is_overlapping(AddrRange(0x1FFF, 0x1))
True
>>> AddrRange(0x1000, '4 KB').is_overlapping(AddrRange(0x1000, '4 KB'))
True
>>> AddrRange(0x3000, '4 KB').is_overlapping(AddrRange(0x2000, '4 KB'))
False
>>> AddrRange(0x3000, '4 KB').is_overlapping(AddrRange(0x2FFF, 0x1))
False
>>> AddrRange(0x3000, '4 KB').is_overlapping(AddrRange(0x3000, 0x1))
True
>>> AddrRange(0x3000, '4 KB').is_overlapping(AddrRange(0x0000, 0x8000))
True
get_intersect
Return intersection of self and other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other(AddrRange)
|
The other AddrRange for intersection with |
required |
Other Parameters:
| Name | Type | Description |
|---|---|---|
strict(bool) |
Raise |
Absolute AddrRanges just lead to the intersection:
>>> AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x2000, '4 KB'))
>>> AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x2000, 0x1))
>>> AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x1FFF, 0x1))
AddrRange(0x1FFF, '1 byte')
Remark: humandfriendly package is rounding 4095 bytes to 4 KB.
>>> a = AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x1000, 0xFFF))
>>> a
AddrRange(0x1000, '4095 bytes')
>>> int(a.size)
4095
>>> AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x1000, '4 KB'))
AddrRange(0x1000, '4 KB')
>>> AddrRange(0x3000, '4 KB').get_intersect(AddrRange(0x2000, '4 KB'))
>>> AddrRange(0x3000, '4 KB').get_intersect(AddrRange(0x2FFF, 0x1))
>>> AddrRange(0x3000, '4 KB').get_intersect(AddrRange(0x3000, 0x1))
AddrRange(0x3000, '1 byte')
>>> AddrRange(0x3000, '4 KB').get_intersect(AddrRange(0x0000, 0x8000))
AddrRange(0x3000, '4 KB')
If strict is set and there is no insersection IntersectError is raised:
>>> AddrRange(0x1000, '4 KB').get_intersect(AddrRange(0x1000, '4 KB'), strict=True)
AddrRange(0x1000, '4 KB')
>>> AddrRange(0x1000, '4 KB').get_intersect(
... AddrRange(0x3000, '4 KB'), strict=True) # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
icdutil.addrrange.IntersectError: No intersection between AddrRange(0x1000, '4 KB') and AddrRange(0x3000, '4 KB').
If only one of the AddrRange is absolute, the sub range is taken relative to the absolute.
If self is a subrange, then the intersection is again a subrange w/r/t to the absolute range.
>>> AddrRange(0xF0000000, '1 MB').get_intersect(AddrRange(0x2000, '4 KB', is_sub=True))
AddrRange(0xF0002000, '4 KB')
>>> AddrRange(0x2000, '4 KB', is_sub=True).get_intersect(AddrRange(0xF0000000, '1 MB'))
AddrRange(0x2000, '4 KB', is_sub=True)
If there is no overlap b/w absolute range and sub-range at the offset,
the result depends on the strict parameter:
>>> AddrRange(0xF0000000, '1 KB').get_intersect(AddrRange(0x2000, '4 KB', is_sub=True))
>>> AddrRange(0xF0000000, '1 KB').get_intersect(
... AddrRange(0x2000, '4 KB', is_sub=True), strict=True) # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
icdutil.addrrange.IntersectError: No intersection between AddrRange(0xF0000000, '1 KB') and AddrRange(0x2000, '4 KB', is_sub=True).
If both are sub-ranges it also just leads to an intersection, but the result is a sub-range:
>>> AddrRange(0x3000, '4 KB', is_sub=True).get_intersect(AddrRange(0x0000, 0x8000, is_sub=True))
AddrRange(0x3000, '4 KB', is_sub=True)
The item and aaddrwidth of the intersection is always inherited from self.
>>> AddrRange(0x2000, '1 MB', item='A', addrwidth=20).get_intersect(
... AddrRange(0x5000, '4 KB', item='B', addrwidth=24))
AddrRange('A', 0x05000, '4 KB', addrwidth=20)
get_difference
Get difference of self and other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other(AddrRange)
|
The other AddrRange for intersection with |
required |
Absolute AddrRanges just lead to the difference (i.e. the rest of self after the overlapping part
has been removed):
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x2000, '4 KB'))
[AddrRange(0x1000, '4 KB')]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x800, '12 KB'))
[]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x1FFF, 0x1))
[AddrRange(0x1000, '4095 bytes')]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x1001, '8 KB'))
[AddrRange(0x1000, '1 byte')]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x1000, 0xFFF))
[AddrRange(0x1FFF, '1 byte')]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x1800, 0x1))
[AddrRange(0x1000, '2 KB'), AddrRange(0x1801, '2047 bytes')]
If both are sub-ranges it also just leads to a difference, but the result is a sub-range:
>>> AddrRange(0x1000, '4 KB', is_sub=True).get_difference(AddrRange(0x2000, '4 KB', is_sub=True))
[AddrRange(0x1000, '4 KB', is_sub=True)]
>>> AddrRange(0x1000, '4 KB', is_sub=True).get_difference(AddrRange(0x800, '12 KB', is_sub=True))
[]
>>> AddrRange(0x1000, '4 KB', is_sub=True).get_difference(AddrRange(0x1FFF, 0x1, is_sub=True))
[AddrRange(0x1000, '4095 bytes', is_sub=True)]
If only one of the AddrRange is absolute, the sub range is taken relative to the absolute.
If self is a subrange, then the difference is again a subrange w/r/t to the absolute range.
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x2000, '4 KB', is_sub=True))
[AddrRange(0x1000, '4 KB')]
>>> AddrRange(0x1000, '4 KB', is_sub=True).get_difference(AddrRange(0x2000, '4 KB'))
[AddrRange(0x1000, '4 KB', is_sub=True)]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x800, '2 KB', is_sub=True))
[AddrRange(0x1000, '2 KB')]
>>> AddrRange(0x1000, '4 KB').get_difference(AddrRange(0x800, '1 KB', is_sub=True))
[AddrRange(0x1000, '2 KB'), AddrRange(0x1C00, '1 KB')]
>>> AddrRange(0x1000, '4 KB', is_sub=True).get_difference(AddrRange(0x800, '4 KB'))
[AddrRange(0x1000, '4 KB', is_sub=True)]
>>> AddrRange(0x400, '4 KB', is_sub=True).get_difference(AddrRange(0xF0000800, '4 KB'))
[AddrRange(0x1000, '1 KB', is_sub=True)]
Regardless of the other range, the difference always inherits addrwidth, the item (if there is any) and
the is_sub attribute:
>>> AddrRange(0x1000, '4 KB', item='A').get_difference(AddrRange(0x1800, '4 KB', item='B'))
[AddrRange('A', 0x1000, '2 KB')]
>>> AddrRange(0x1000, '4 KB', addrwidth=16).get_difference(AddrRange(0x1800, '4 KB', addrwidth=18))
[AddrRange(0x1000, '2 KB', addrwidth=16)]
IntersectError
Bases: RuntimeError
AddrRange Intersection Error.