<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _hook_mem_unmapped(self, uc, access, address, size, value, user_data, size_extension=True):
 #pylint:disable=unused-argument """ This callback is called when unicorn needs to access data that's not yet present in memory. """

        # FIXME check angr hooks at `address`

        if size_extension:
            start = address & (0xfffffffffffff0000)
            length = ((address + size + 0xffff) & (0xfffffffffffff0000)) - start
        else:
            start = address & (0xffffffffffffff000)
            length = ((address + size + 0xfff) & (0xffffffffffffff000)) - start

        if (start == 0 or ((start + length) & ((1 << self.state.arch.bits) - 1)) == 0) and options.UNICORN_ZEROPAGE_GUARD in self.state.options:
            # sometimes it happens because of %fs is not correctly set
            self.error = 'accessing zero page [%#x, %#x] (%#x)' % (address, address + length - 1, access)
            l.warning(self.error)

            # tell uc_state to rollback
            _UC_NATIVE.stop(self._uc_state, STOP.STOP_ZEROPAGE)
            return False

        ret = False
        try:
            best_effort_read = size_extension
            ret = self._hook_mem_unmapped_core(uc, access, start, length, best_effort_read=best_effort_read)

        except AccessingZeroPageError:
            # raised when STRICT_PAGE_ACCESS is enabled
            if not size_extension:
                _UC_NATIVE.stop(self._uc_state, STOP.STOP_SEGFAULT)
                ret = False

        except FetchingZeroPageError:
            # raised when trying to execute code on an unmapped page
            if not size_extension:
                self.error = 'fetching empty page [%#x, %#x]' % (start, start + length - 1)
                l.warning(self.error)
                _UC_NATIVE.stop(self._uc_state, STOP.STOP_EXECNONE)
                ret = False

        except SimMemoryError:
            if not size_extension:
                raise

        except SegfaultError:
            if not size_extension:
                _UC_NATIVE.stop(self._uc_state, STOP.STOP_SEGFAULT)
                ret = False

        except MixedPermissonsError:
            if not size_extension:
                # weird... it shouldn't be raised at all
                l.error('MixedPermissionsError is raised when size-extension is disabled. Please report it.')
                _UC_NATIVE.stop(self._uc_state, STOP.STOP_SEGFAULT)
                ret = False

        except unicorn.UcError as ex:
            if not size_extension:
                if ex.errno == 11:
                    # Mapping failed. Probably because of size extension... let's try to redo it without size extension
                    pass
                else:
                    # just raise the exception
                    raise

        finally:
            if size_extension and not ret:
                # retry without size-extension if size-extension was enabled
                # any exception will not be caught
                ret = self._hook_mem_unmapped(uc, access, address, size, value, user_data, size_extension=False)

        return ret