'Get virtual memory mapping address ranges of debugged process
Args:
- name: name/address of binary/library to get mapping range (String)
+ name = "binary" means debugged program
+ name = "all" means all virtual maps
Returns:
- list of virtual mapping ranges (start(Int), end(Int), permission(String), mapname(String))'

@memoized
def get_vmmap(self, name=None):

    def _get_offline_maps():
        name = self.getfile()
        if (not name):
            return None
        headers = self.elfheader()
        binmap = []
        hlist = [x for x in headers.items() if (x[1][2] == 'code')]
        hlist = sorted(hlist, key=(lambda x: x[1][0]))
        binmap += [(hlist[0][1][0], hlist[(-1)][1][1], 'rx-p', name)]
        hlist = [x for x in headers.items() if (x[1][2] == 'rodata')]
        hlist = sorted(hlist, key=(lambda x: x[1][0]))
        binmap += [(hlist[0][1][0], hlist[(-1)][1][1], 'r--p', name)]
        hlist = [x for x in headers.items() if (x[1][2] == 'data')]
        hlist = sorted(hlist, key=(lambda x: x[1][0]))
        binmap += [(hlist[0][1][0], hlist[(-1)][1][1], 'rw-p', name)]
        return binmap
    def _get_allmaps_osx(pid, remote=False):
        maps = []
        pattern = re.compile('([^\n]*)\\s*        ([0-9a-f][^-\\s]*)-([^\\s]*)    \\[.*\\]\\s([^/]*).*        (.*)')
        if remote:
            return maps
        else:
            try:
                out = execute_external_command(('/usr/bin/vmmap    -w    %s' % self.getpid()))
            except:
                error_msg('could    not    read    vmmap    of    process')
        matches = pattern.findall(out)
        if matches:
            for (name, start, end, perm, mapname) in matches:
                if name.startswith('Stack'):
                    mapname = '[stack]'
                start = to_int(('0x%s' % start))
                end = to_int(('0x%s' % end))
                if (mapname == ''):
                    mapname = name.strip()
                maps += [(start, end, perm, mapname)]
        return maps
    def _get_allmaps_freebsd(pid, remote=False):
        maps = []
        mpath = ('/proc/%s/map' % pid)
        pattern = re.compile('0x([0-9a-f]*)    0x([0-9a-f]*)(?:    [^    ]*){3}    ([rwx-]*)(?:    [^    ]*){6}    ([^    ]*)')
        if remote:
            return maps
        else:
            try:
                out = open(mpath).read()
            except:
                error_msg(('could    not    open    %s;    is    procfs    mounted?' % mpath))
        matches = pattern.findall(out)
        if matches:
            for (start, end, perm, mapname) in matches:
                if ((start[:2] in ['bf', '7f', 'ff']) and ('rw' in perm)):
                    mapname = '[stack]'
                start = to_int(('0x%s' % start))
                end = to_int(('0x%s' % end))
                if (mapname == '-'):
                    if ((start == maps[(-1)][1]) and (maps[(-1)][(-1)][0] == '/')):
                        mapname = maps[(-1)][(-1)]
                    else:
                        mapname = 'mapped'
                maps += [(start, end, perm, mapname)]
        return maps
    def _get_allmaps_linux(pid, remote=False):
        maps = []
        mpath = ('/proc/%s/maps' % pid)
        pattern = re.compile('([0-9a-f]*)-([0-9a-f]*)    ([rwxps-]*)(?:    [^    ]*){3}    *(.*)')
        if remote:
            tmp = tmpfile()
            self.execute(('remote    get    %s    %s' % (mpath, tmp.name)))
            tmp.seek(0)
            out = tmp.read()
            tmp.close()
        else:
            out = open(mpath).read()
        matches = pattern.findall(out)
        if matches:
            for (start, end, perm, mapname) in matches:
                start = to_int(('0x%s' % start))
                end = to_int(('0x%s' % end))
                if (mapname == ''):
                    mapname = 'mapped'
                maps += [(start, end, perm, mapname)]
        return maps
    result = []
    pid = self.getpid()
    if (not pid):
        try:
            return _get_offline_maps()
        except:
            return []
    os = self.getos()
    rmt = self.is_target_remote()
    maps = []
    try:
        if (os == 'FreeBSD'):
            maps = _get_allmaps_freebsd(pid, rmt)
        elif (os == 'Linux'):
            maps = _get_allmaps_linux(pid, rmt)
        elif (os == 'Darwin'):
            maps = _get_allmaps_osx(pid, rmt)
    except Exception as e:
        if (config.Option.get('debug') == 'on'):
            msg(('Exception:    %s' % e))
            traceback.print_exc()
    if (name == 'binary'):
        name = self.getfile()
    if ((name is None) or (name == 'all')):
        name = ''
    if (to_int(name) is None):
        for (start, end, perm, mapname) in maps:
            if (name in mapname):
                result += [(start, end, perm, mapname)]
    else:
        addr = to_int(name)
        for (start, end, perm, mapname) in maps:
            if ((start <= addr) and (addr < end)):
                result += [(start, end, perm, mapname)]
    return result
