'Get a segmented memory region based on AbstractLocation information available from VSA.
Here are some assumptions to make this method fast:
- The entire memory region [addr, addr + size] is located within the same MemoryRegion
- The address \'addr\' has only one concrete value. It cannot be concretized to multiple values.
:param addr: An address
:param size: Size of the memory area in bytes
:return: An ordered list of sizes each segment in the requested memory region'

def get_segments(self, addr, size):

    address_wrappers = self.normalize_address(addr, is_write=False)
    aw = address_wrappers[0]
    region_id = aw.region
    if (region_id in self.regions):
        region = self.regions[region_id]
        alocs = region.get_abstract_locations(aw.address, size)
        segments = []
        for aloc in alocs:
            segments.extend(aloc.segments)
        segments = sorted(segments, key=(lambda x: x.offset))
        processed_segments = []
        last_seg = None
        for seg in segments:
            if (last_seg is None):
                last_seg = seg
                processed_segments.append(seg)
            else:
                if ((seg.offset >= last_seg.offset) and (seg.offset <= (last_seg.offset + size))):
                    continue
                processed_segments.append(seg)
        sizes = []
        next_pos = aw.address
        for seg in processed_segments:
            if (seg.offset > next_pos):
                gap = (seg.offset - next_pos)
                assert (gap > 0)
                sizes.append(gap)
                next_pos += gap
            if ((seg.size + next_pos) > (aw.address + size)):
                sizes.append(((aw.address + size) - next_pos))
                next_pos += ((aw.address + size) - next_pos)
            else:
                sizes.append(seg.size)
                next_pos += seg.size
        if (len(sizes) == 0):
            return [size]
        return sizes
    else:
        return [size]
