icdutil.addrrange module

Helper Class For Handling Address Ranges.

class icdutil.addrrange.AddrRange(*args, **kwargs)[source]

Bases: NewBase

Address range starting at baseaddr with size in bytes.

addrwidth: Optional[int]
baseaddr: Hex
property endaddr: Hex

Hexvalue of end address of range.

get_difference(other: AddrRange) List[AddrRange][source]

Get difference of self and other.

Parameters:

other (AddrRange) – The other AddrRange for intersection with self.

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, '4 KB')]
>>> 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, '2 KB')]

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, '4 KB', 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)]
get_intersect(other: AddrRange, strict: bool = False) Optional[AddrRange][source]

Return intersection of self and other.

Parameters:

other (AddrRange) – The other AddrRange for intersection with self.

Keyword Arguments:

strict (bool) – Raise IntersectError when True and there is no intersection between self and other.

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, '4 KB')
>>> 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)  
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)  
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)
is_overlapping(other: AddrRange) bool[source]

Return True if other overlaps.

>>> 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
is_sub: bool
item: Optional[Any]
property nextaddr: Hex

Hexvalue of first address after range.

size: Bytes
exception icdutil.addrrange.IntersectError[source]

Bases: RuntimeError

AddrRange Intersection Error.