'Convert an absolute address to the memory offset in a memory region.
Note that if an address belongs to heap region is passed in to a stack region map, it will be converted to an
offset included in the closest stack frame, and vice versa for passing a stack address to a heap region.
Therefore you should only pass in address that belongs to the same category (stack or non-stack) of this region
map.
:param absolute_address:    An absolute memory address
:return:                    A tuple of the closest region ID, the relative offset, and the related function
address.'

def relativize(self, absolute_address, target_region_id=None):

    if (target_region_id is None):
        if self.is_stack:
            base_address = self._address_to_region_id.ceiling_key(absolute_address)
        else:
            try:
                base_address = self._address_to_region_id.floor_key(absolute_address)
            except KeyError:
                return ('global', absolute_address, None)
        descriptor = self._address_to_region_id[base_address]
    else:
        if (target_region_id == 'global'):
            return ('global', absolute_address, None)
        if (target_region_id not in self._region_id_to_address):
            raise SimRegionMapError(('Trying    to    relativize    to    a    non-existent    region    "%s"' % target_region_id))
        descriptor = self._region_id_to_address[target_region_id]
        base_address = descriptor.base_address
    return (descriptor.region_id, (absolute_address - base_address), descriptor.related_function_address)
