Exemple #1
0
 def __init__(self, machine, alloc, segloader, cfg, main_profiler=None):
     self.mem = machine.get_mem()
     self.cfg = cfg
     self.vlib_mgr = VLibManager(machine,
                                 alloc,
                                 main_profiler=main_profiler)
     self.alib_mgr = ALibManager(machine, alloc, segloader)
     cfg.dump(log_libmgr.info)
Exemple #2
0
 def __init__(self, machine, alloc, segloader, cfg, main_profiler=None):
     self.mem = machine.get_mem()
     self.cfg = cfg
     self.machine = machine
     self.vlib_mgr = VLibManager(machine,
                                 alloc,
                                 main_profiler=main_profiler)
     self.alib_mgr = ALibManager(machine, alloc, segloader)
     self.proxy_mgr = LibProxyManager(self)
     # inject proxy mgr into all ctx
     self.vlib_mgr.set_ctx_extra_attr("proxies", self.proxy_mgr)
     cfg.dump(log_libmgr.info)
Exemple #3
0
def libnative_mgr_fail_test():
    machine, alloc, sp, mem, exec_lib = setup()

    # load

    class PathMgrMock:
        def ami_to_sys_path(self, lock, ami_path, mustExist=True):
            return None

    pm = PathMgrMock()
    segload = SegmentLoader(alloc, pm)
    mgr = ALibManager(machine, alloc, segload)
    # open_lib
    lib_base = mgr.open_lib("testnix.library", run_sp=sp)
    assert lib_base == 0
    # close lib
    with pytest.raises(ValueError):
        mgr.close_lib(lib_base, run_sp=sp)
    # expunge lib
    with pytest.raises(ValueError):
        mgr.expunge_lib(lib_base, run_sp=sp)
    # expunge lib
    left = mgr.shutdown(run_sp=sp)
    assert left == 0
    # cleanup
    exec_lib.free()
    assert alloc.is_all_free()
Exemple #4
0
 def __init__(self, machine, alloc, segloader, cfg,
              main_profiler=None):
   self.mem = machine.get_mem()
   self.cfg = cfg
   self.vlib_mgr = VLibManager(machine, alloc,
                               main_profiler=main_profiler)
   self.alib_mgr = ALibManager(machine, alloc, segloader)
   cfg.dump(log_libmgr.info)
Exemple #5
0
def libnative_mgr_fail_test():
  machine, alloc, sp, mem, exec_lib = setup()
  # load

  class PathMgrMock:
    def ami_to_sys_path(self, lock, ami_path, mustExist=True):
      return None

  pm = PathMgrMock()
  segload = SegmentLoader(alloc, pm)
  mgr = ALibManager(machine, alloc, segload)
  # open_lib
  lib_base = mgr.open_lib("testnix.library", run_sp=sp)
  assert lib_base == 0
  # close lib
  with pytest.raises(ValueError):
    mgr.close_lib(lib_base, run_sp=sp)
  # expunge lib
  with pytest.raises(ValueError):
    mgr.expunge_lib(lib_base, run_sp=sp)
  # expunge lib
  left = mgr.shutdown(run_sp=sp)
  assert left == 0
  # cleanup
  exec_lib.free()
  assert alloc.is_all_free()
Exemple #6
0
def libnative_mgr_test(buildlibnix):
    if buildlibnix.flavor not in ("gcc", "gcc-dbg"):
        pytest.skip("only single base lib supported")
    log_libmgr.setLevel(logging.INFO)
    machine, alloc, sp, mem, exec_lib = setup()
    # load
    lib_file = buildlibnix.make_lib("testnix")

    class PathMgrMock:
        def ami_to_sys_path(self, lock, ami_path, mustExist=True):
            if ami_path == "LIBS:testnix.library":
                return lib_file

    pm = PathMgrMock()
    segload = SegmentLoader(alloc, pm)
    mgr = ALibManager(machine, alloc, segload)
    # open_lib
    lib_base = mgr.open_lib("testnix.library", run_sp=sp)
    assert lib_base > 0
    assert mgr.is_base_addr(lib_base)
    lib_info = mgr.get_lib_info_for_name("testnix.library")
    assert lib_info
    assert lib_info.is_base_addr(lib_base)
    assert lib_info.get_lib_fd()
    # close lib
    seglist = mgr.close_lib(lib_base, run_sp=sp)
    assert seglist == 0
    lib_info = mgr.get_lib_info_for_name("testnix.library")
    assert lib_info
    assert not lib_info.is_base_addr(lib_base)
    # expunge lib
    left = mgr.shutdown(run_sp=sp)
    assert left == 0
    assert not mgr.is_base_addr(lib_base)
    lib_info = mgr.get_lib_info_for_name("testnix.library")
    assert not lib_info
    # we have to manually clean the lib here (as Exec FreeMem() does not work)
    free_lib(mem, alloc, lib_base)
    # cleanup
    exec_lib.free()
    assert alloc.is_all_free()
Exemple #7
0
def libnative_mgr_test(buildlibnix):
  if buildlibnix.flavor not in ('gcc', 'gcc-dbg'):
    pytest.skip("only single base lib supported")
  log_libmgr.setLevel(logging.INFO)
  machine, alloc, sp, mem, exec_lib = setup()
  # load
  lib_file = buildlibnix.make_lib('testnix')

  class PathMgrMock:
    def ami_to_sys_path(self, lock, ami_path, mustExist=True):
      if ami_path == 'LIBS:testnix.library':
        return lib_file

  pm = PathMgrMock()
  segload = SegmentLoader(alloc, pm)
  mgr = ALibManager(machine, alloc, segload)
  # open_lib
  lib_base = mgr.open_lib("testnix.library", run_sp=sp)
  assert lib_base > 0
  assert mgr.is_base_addr(lib_base)
  lib_info = mgr.get_lib_info_for_name("testnix.library")
  assert lib_info
  assert lib_info.is_base_addr(lib_base)
  # close lib
  seglist = mgr.close_lib(lib_base, run_sp=sp)
  assert seglist == 0
  lib_info = mgr.get_lib_info_for_name("testnix.library")
  assert lib_info
  assert not lib_info.is_base_addr(lib_base)
  # expunge lib
  left = mgr.shutdown(run_sp=sp)
  assert left == 0
  assert not mgr.is_base_addr(lib_base)
  lib_info = mgr.get_lib_info_for_name("testnix.library")
  assert not lib_info
  # we have to manually clean the lib here (as Exec FreeMem() does not work)
  lib = Library(mem, lib_base, alloc)
  lib.free()
  # cleanup
  exec_lib.free()
  assert alloc.is_all_free()
Exemple #8
0
class LibManager(object):
    """the library manager handles both native and vamos libs"""
    def __init__(self, machine, alloc, segloader, cfg, main_profiler=None):
        self.mem = machine.get_mem()
        self.cfg = cfg
        self.vlib_mgr = VLibManager(machine,
                                    alloc,
                                    main_profiler=main_profiler)
        self.alib_mgr = ALibManager(machine, alloc, segloader)
        cfg.dump(log_libmgr.info)

    def add_ctx(self, name, ctx):
        """allow to add vlib contexts"""
        ctx.lib_mgr = self
        self.vlib_mgr.add_ctx(name, ctx)

    def add_impl_cls(self, name, impl_cls):
        """allow to add vlib impl classes"""
        self.vlib_mgr.add_impl_cls(name, impl_cls)

    def get_vlib_by_addr(self, addr):
        """return associated vlib for a base lib address"""
        return self.vlib_mgr.get_vlib_by_addr(addr)

    def get_vlib_by_name(self, name):
        """return associated vlib for a name"""
        return self.vlib_mgr.get_vlib_by_name(name)

    def bootstrap_exec(self, exec_info=None):
        """setup exec vlib as first and essential lib"""
        version = 0
        lib_cfg = self.cfg.get_lib_cfg("exec.library")
        force_version = lib_cfg.get_force_version()
        if force_version is not None:
            version = force_version
            log_libmgr.info("exec: force version: %s", version)
        return self.vlib_mgr.bootstrap_exec(exec_info, version)

    def shutdown(self, run_sp=None):
        """cleanup libs

        try to expunge all libs and report still open ones
        """
        log_libmgr.info("+shutdown")
        aleft = self.alib_mgr.shutdown(run_sp)
        if aleft > 0:
            log_libmgr.warning("shutdown: can't expunge %d amiga libs/devs!",
                               aleft)
        vleft = self.vlib_mgr.shutdown()
        if vleft > 0:
            log_libmgr.warning("shutdown: can't expunge %d vamos libs/devs!",
                               vleft)
        left = vleft + aleft
        log_libmgr.info("-shutdwon: aleft=%d, vleft=%d", aleft, vleft)
        return left

    def expunge_libs(self, run_sp=None):
        """expunge all unused libs

        return number of libs _not_ expunged
        """
        log_libmgr.info("+expunge_libs")
        aleft = self.alib_mgr.expunge_libs(run_sp)
        vleft = self.vlib_mgr.expunge_libs()
        log_libmgr.info("-expunge_libs: aleft=%d, vleft=%d", aleft, vleft)
        return vleft + aleft

    def expunge_devs(self, run_sp=None):
        """expunge all unused devs

        return number of libs _not_ expunged
        """
        log_libmgr.info("+expunge_devs")
        aleft = 0  # TBD
        vleft = self.vlib_mgr.expunge_devs()
        log_libmgr.info("-expunge_devs: aleft=%d, vleft=%d", aleft, vleft)
        return vleft

    def expunge_lib(self, addr, run_sp=None):
        """expunge a library given by base address

        return True if lib was expunged
        """
        log_libmgr.info("expunge_lib: @%06x", addr)
        vlib = self.vlib_mgr.get_vlib_by_addr(addr)
        if vlib:
            return self.vlib_mgr.expunge_lib(vlib)
        elif self.alib_mgr.is_load_addr(addr):
            seglist = self.alib_mgr.expunge_lib(addr, run_sp)
            return seglist != 0
        else:
            log_libmgr.error("expunge: unknown lib @%06x!", addr)

    def close_lib(self, addr, run_sp=None):
        """close a library

        return True if lib was expunged, too
        """
        log_libmgr.info("close_lib: @%06x", addr)
        vlib = self.vlib_mgr.get_vlib_by_addr(addr)
        if vlib:
            return self.vlib_mgr.close_lib(vlib)
        elif self.alib_mgr.is_base_addr(addr):
            seglist = self.alib_mgr.close_lib(addr, run_sp)
            return seglist != 0
        else:
            log_libmgr.error("close: unknown lib @%06x!", addr)

    def open_lib(self,
                 full_name,
                 version=0,
                 cwd_lock=None,
                 run_sp=None,
                 progdir_lock=None):
        """open a library

        return lib_base addr or 0
        """
        # get base name
        base_name = LibLoader.get_lib_base_name(full_name)
        log_libmgr.info("open_lib: '%s' ver=%d -> base_name='%s'", full_name,
                        version, base_name)
        # get lib params
        lib_cfg = self.cfg.get_cfg(full_name, base_name)
        log_libmgr.info("-> cfg: %s", lib_cfg)
        # handle mode
        mode = lib_cfg.get_create_mode()
        if mode == LibCfg.CREATE_MODE_OFF:
            return 0
        try_vlib, try_alib, fake = self._map_mode(mode)

        # try vamos first
        addr = 0
        vlib = None
        if try_vlib:
            # get presented version of lib
            lib_version = 0
            force_version = lib_cfg.get_force_version()
            if force_version is not None:
                lib_version = force_version
            log_libmgr.info("vlib: version=%d, fake=%s", lib_version, fake)
            # open vlib
            vlib = self.vlib_mgr.open_lib_name(base_name,
                                               version=lib_version,
                                               fake=fake,
                                               lib_cfg=lib_cfg)
            if vlib:
                addr = vlib.get_addr()
                log_libmgr.info("got vlib: @%06x", addr)

        # try amiga lib
        if try_alib and addr == 0:
            addr = self.alib_mgr.open_lib(full_name, cwd_lock, run_sp,
                                          progdir_lock)
            if addr > 0:
                log_libmgr.info("got alib: @%06x", addr)

        # got a lib? check version
        if addr > 0:
            save_addr = addr
            if version > 0:
                addr = self._check_version(full_name, addr, version)
            # lib is too old: close again
            if addr == 0:
                if vlib:
                    self.vlib_mgr.close_lib(vlib)
                else:
                    self.alib_mgr.close_lib(save_addr, run_sp=run_sp)

        # result lib base
        return addr

    def _map_mode(self, mode):
        if mode == LibCfg.CREATE_MODE_AUTO:
            try_vlib = True
            try_alib = True
            fake = False
        elif mode == LibCfg.CREATE_MODE_VAMOS:
            try_vlib = True
            try_alib = False
            fake = False
        elif mode == LibCfg.CREATE_MODE_AMIGA:
            try_vlib = False
            try_alib = True
            fake = False
        elif mode == LibCfg.CREATE_MODE_FAKE:
            try_vlib = True
            try_alib = False
            fake = True
        else:
            raise ValueError("invalid lib mode: '%s'" % mode)
        return try_vlib, try_alib, fake

    def _check_version(self, name, addr, open_ver):
        # check version
        lib = Library(self.mem, addr)
        lib_ver = lib.version
        if lib_ver < open_ver:
            log_libmgr.warning("lib '%s' has too low version: %d < %d", name,
                               lib_ver, open_ver)
            return 0
        else:
            log_libmgr.info("lib '%s' version %d ok for open version %d", name,
                            lib_ver, open_ver)
            return addr
Exemple #9
0
class LibManager(object):
    """the library manager handles both native and vamos libs"""

    MODE_OFF = 'off'
    MODE_AUTO = 'auto'
    MODE_VAMOS = 'vamos'
    MODE_AMIGA = 'amiga'
    MODE_FAKE = 'fake'

    def __init__(self, machine, alloc, segloader, cfg=None, profiler_cfg=None):
        self.mem = machine.get_mem()
        self.cfg = cfg
        self.vlib_mgr = VLibManager(machine, alloc, profiler_cfg=profiler_cfg)
        self.alib_mgr = ALibManager(machine, alloc, segloader)

    def add_ctx(self, name, ctx):
        """allow to add vlib contexts"""
        ctx.lib_mgr = self
        self.vlib_mgr.add_ctx(name, ctx)

    def get_vlib_by_addr(self, addr):
        """return associated vlib for a base lib address"""
        return self.vlib_mgr.get_vlib_by_addr(addr)

    def get_vlib_by_name(self, name):
        """return associated vlib for a name"""
        return self.vlib_mgr.get_vlib_by_name(name)

    def bootstrap_exec(self, exec_info=None):
        """setup exec vlib as first and essential lib"""
        lib_cfg = None
        if self.cfg:
            lib_cfg = self.cfg.get_lib_config("exec.library")
        return self.vlib_mgr.bootstrap_exec(exec_info)

    def shutdown(self, run_sp=None):
        """cleanup libs

    try to expunge all libs and report still open ones
    """
        log_libmgr.info("+shutdown")
        aleft = self.alib_mgr.shutdown(run_sp)
        if aleft > 0:
            log_libmgr.warn("shutdown: can't expunge %d amiga libs/devs!",
                            aleft)
        vleft = self.vlib_mgr.shutdown()
        if vleft > 0:
            log_libmgr.warn("shutdown: can't expunge %d vamos libs/devs!",
                            vleft)
        left = vleft + aleft
        log_libmgr.info("-shutdwon: aleft=%d, vleft=%d", aleft, vleft)
        return left

    def expunge_libs(self, run_sp=None):
        """expunge all unused libs

       return number of libs _not_ expunged
    """
        log_libmgr.info("+expunge_libs")
        aleft = self.alib_mgr.expunge_libs(run_sp)
        vleft = self.vlib_mgr.expunge_libs()
        log_libmgr.info("-expunge_libs: aleft=%d, vleft=%d", aleft, vleft)
        return vleft + aleft

    def expunge_devs(self, run_sp=None):
        """expunge all unused devs

       return number of libs _not_ expunged
    """
        log_libmgr.info("+expunge_devs")
        aleft = 0  # TBD
        vleft = self.vlib_mgr.expunge_devs()
        log_libmgr.info("-expunge_devs: aleft=%d, vleft=%d", aleft, vleft)
        return vleft

    def expunge_lib(self, addr, run_sp=None):
        """expunge a library given by base address

       return True if lib was expunged
    """
        log_libmgr.info("expunge_lib: @%06x", addr)
        vlib = self.vlib_mgr.get_vlib_by_addr(addr)
        if vlib:
            return self.vlib_mgr.expunge_lib(vlib)
        elif self.alib_mgr.is_load_addr(addr):
            seglist = self.alib_mgr.expunge_lib(addr, run_sp)
            return seglist != 0
        else:
            log_libmgr.error("expunge: unknown lib @%06x!", addr)

    def close_lib(self, addr, run_sp=None):
        """close a library

       return True if lib was expunged, too
    """
        log_libmgr.info("close_lib: @%06x", addr)
        vlib = self.vlib_mgr.get_vlib_by_addr(addr)
        if vlib:
            return self.vlib_mgr.close_lib(vlib)
        elif self.alib_mgr.is_base_addr(addr):
            seglist = self.alib_mgr.close_lib(addr, run_sp)
            return seglist != 0
        else:
            log_libmgr.error("close: unknown lib @%06x!", addr)

    def open_lib(self,
                 full_name,
                 open_ver=0,
                 lock=None,
                 run_sp=None,
                 mode=None,
                 version=None):
        """open a library

       return lib_base addr or 0
    """
        # get base name
        base_name = LibLoader.get_lib_base_name(full_name)
        log_libmgr.info("open_lib: '%s' ver=%d -> base_name='%s'", full_name,
                        open_ver, base_name)
        # get lib params
        mode, version = self._get_lib_params(full_name, base_name, mode,
                                             version)
        log_libmgr.info("params: mode=%s, version=%d", mode, version)
        # handle mode
        if mode == self.MODE_OFF:
            return 0
        try_vlib, try_alib, fake = self._map_mode(mode)

        # try vamos first
        addr = 0
        vlib = None
        if try_vlib:
            vlib = self.vlib_mgr.open_lib_name(base_name,
                                               version=version,
                                               fake=fake)
            if vlib:
                addr = vlib.get_addr()
                log_libmgr.info("got vlib: @%06x", addr)
        # try amiga lib
        if try_alib and addr == 0:
            addr = self.alib_mgr.open_lib(full_name, lock, run_sp)
            if addr > 0:
                log_libmgr.info("got alib: @%06x", addr)

        # got a lib? check version
        if addr > 0:
            save_addr = addr
            if open_ver > 0:
                addr = self._check_version(full_name, addr, open_ver)
            # lib is too old: close again
            if addr == 0:
                if vlib:
                    self.vlib_mgr.close_lib(vlib)
                else:
                    self.alib_mgr.close_lib(save_addr, run_sp=run_sp)
        # result lib base
        return addr

    def _map_mode(self, mode):
        if mode == self.MODE_AUTO:
            try_vlib = True
            try_alib = True
            fake = False
        elif mode == self.MODE_VAMOS:
            try_vlib = True
            try_alib = False
            fake = False
        elif mode == self.MODE_AMIGA:
            try_vlib = False
            try_alib = True
            fake = False
        elif mode == self.MODE_FAKE:
            try_vlib = True
            try_alib = False
            fake = True
        else:
            raise ValueError("invalid lib mode: '%s'" % mode)
        return try_vlib, try_alib, fake

    def _check_version(self, name, addr, open_ver):
        # check version
        lib = Library(self.mem, addr)
        lib_ver = lib.version
        if lib_ver < open_ver:
            log_libmgr.warn("lib '%s' has too low version: %d < %d", name,
                            lib_ver, open_ver)
            return 0
        else:
            log_libmgr.info("lib '%s' version %d ok for open version %d", name,
                            lib_ver, open_ver)
            return addr

    def _get_lib_params(self, full_name, base_name, force_mode, force_version):
        # get lib config
        if self.cfg:
            lib_cfg = self.cfg.get_lib_config(full_name, base_name)
            self._dump_lib_cfg(full_name, lib_cfg)
            mode = lib_cfg.mode
            version = lib_cfg.version
        else:
            lib_cfg = None
            mode = "auto"
            version = 0  # take lib version
        if force_mode:
            mode = force_mode
        if force_version:
            version = force_version
        return mode, version

    def _dump_lib_cfg(self, lib_name, lib_cfg):
        items = ["for_lib='%s'" % lib_name, "use_cfg='%s'" % lib_cfg.name]
        for key in lib_cfg._keys:
            items.append("%s=%s" % (key, getattr(lib_cfg, key)))
        log_libmgr.info(" ".join(items))
Exemple #10
0
 def __init__(self, machine, alloc, segloader, cfg=None, profiler_cfg=None):
     self.mem = machine.get_mem()
     self.cfg = cfg
     self.vlib_mgr = VLibManager(machine, alloc, profiler_cfg=profiler_cfg)
     self.alib_mgr = ALibManager(machine, alloc, segloader)
Exemple #11
0
class LibManager(object):
  """the library manager handles both native and vamos libs"""

  def __init__(self, machine, alloc, segloader, cfg,
               main_profiler=None):
    self.mem = machine.get_mem()
    self.cfg = cfg
    self.vlib_mgr = VLibManager(machine, alloc,
                                main_profiler=main_profiler)
    self.alib_mgr = ALibManager(machine, alloc, segloader)
    cfg.dump(log_libmgr.info)

  def add_ctx(self, name, ctx):
    """allow to add vlib contexts"""
    ctx.lib_mgr = self
    self.vlib_mgr.add_ctx(name, ctx)

  def add_impl_cls(self, name, impl_cls):
    """allow to add vlib impl classes"""
    self.vlib_mgr.add_impl_cls(name, impl_cls)

  def get_vlib_by_addr(self, addr):
    """return associated vlib for a base lib address"""
    return self.vlib_mgr.get_vlib_by_addr(addr)

  def get_vlib_by_name(self, name):
    """return associated vlib for a name"""
    return self.vlib_mgr.get_vlib_by_name(name)

  def bootstrap_exec(self, exec_info=None):
    """setup exec vlib as first and essential lib"""
    version = 0
    lib_cfg = self.cfg.get_lib_cfg("exec.library")
    force_version = lib_cfg.get_force_version()
    if force_version is not None:
      version = force_version
      log_libmgr.info("exec: force version: %s", version)
    return self.vlib_mgr.bootstrap_exec(exec_info, version)

  def shutdown(self, run_sp=None):
    """cleanup libs

    try to expunge all libs and report still open ones
    """
    log_libmgr.info("+shutdown")
    aleft = self.alib_mgr.shutdown(run_sp)
    if aleft > 0:
      log_libmgr.warn("shutdown: can't expunge %d amiga libs/devs!", aleft)
    vleft = self.vlib_mgr.shutdown()
    if vleft > 0:
      log_libmgr.warn("shutdown: can't expunge %d vamos libs/devs!", vleft)
    left = vleft + aleft
    log_libmgr.info("-shutdwon: aleft=%d, vleft=%d", aleft, vleft)
    return left

  def expunge_libs(self, run_sp=None):
    """expunge all unused libs

       return number of libs _not_ expunged
    """
    log_libmgr.info("+expunge_libs")
    aleft = self.alib_mgr.expunge_libs(run_sp)
    vleft = self.vlib_mgr.expunge_libs()
    log_libmgr.info("-expunge_libs: aleft=%d, vleft=%d", aleft, vleft)
    return vleft + aleft

  def expunge_devs(self, run_sp=None):
    """expunge all unused devs

       return number of libs _not_ expunged
    """
    log_libmgr.info("+expunge_devs")
    aleft = 0  # TBD
    vleft = self.vlib_mgr.expunge_devs()
    log_libmgr.info("-expunge_devs: aleft=%d, vleft=%d", aleft, vleft)
    return vleft

  def expunge_lib(self, addr, run_sp=None):
    """expunge a library given by base address

       return True if lib was expunged
    """
    log_libmgr.info("expunge_lib: @%06x", addr)
    vlib = self.vlib_mgr.get_vlib_by_addr(addr)
    if vlib:
      return self.vlib_mgr.expunge_lib(vlib)
    elif self.alib_mgr.is_load_addr(addr):
      seglist = self.alib_mgr.expunge_lib(addr, run_sp)
      return seglist != 0
    else:
      log_libmgr.error("expunge: unknown lib @%06x!", addr)

  def close_lib(self, addr, run_sp=None):
    """close a library

       return True if lib was expunged, too
    """
    log_libmgr.info("close_lib: @%06x", addr)
    vlib = self.vlib_mgr.get_vlib_by_addr(addr)
    if vlib:
      return self.vlib_mgr.close_lib(vlib)
    elif self.alib_mgr.is_base_addr(addr):
      seglist = self.alib_mgr.close_lib(addr, run_sp)
      return seglist != 0
    else:
      log_libmgr.error("close: unknown lib @%06x!", addr)

  def open_lib(self, full_name, version=0, cwd_lock=None, run_sp=None,
               progdir_lock=None):
    """open a library

       return lib_base addr or 0
    """
    # get base name
    base_name = LibLoader.get_lib_base_name(full_name)
    log_libmgr.info("open_lib: '%s' ver=%d -> base_name='%s'",
                    full_name, version, base_name)
    # get lib params
    lib_cfg = self.cfg.get_cfg(full_name, base_name)
    log_libmgr.info("-> cfg: %s", lib_cfg)
    # handle mode
    mode = lib_cfg.get_create_mode()
    if mode == LibCfg.CREATE_MODE_OFF:
      return 0
    try_vlib, try_alib, fake = self._map_mode(mode)

    # try vamos first
    addr = 0
    vlib = None
    if try_vlib:
      # get presented version of lib
      lib_version = 0
      force_version = lib_cfg.get_force_version()
      if force_version is not None:
        lib_version = force_version
      log_libmgr.info("vlib: version=%d, fake=%s", lib_version, fake)
      # open vlib
      vlib = self.vlib_mgr.open_lib_name(base_name,
                                         version=lib_version,
                                         fake=fake,
                                         lib_cfg=lib_cfg)
      if vlib:
        addr = vlib.get_addr()
        log_libmgr.info("got vlib: @%06x", addr)

    # try amiga lib
    if try_alib and addr == 0:
      addr = self.alib_mgr.open_lib(full_name, cwd_lock, run_sp, progdir_lock)
      if addr > 0:
        log_libmgr.info("got alib: @%06x", addr)

    # got a lib? check version
    if addr > 0:
      save_addr = addr
      if version > 0:
        addr = self._check_version(full_name, addr, version)
      # lib is too old: close again
      if addr == 0:
        if vlib:
          self.vlib_mgr.close_lib(vlib)
        else:
          self.alib_mgr.close_lib(save_addr, run_sp=run_sp)

    # result lib base
    return addr

  def _map_mode(self, mode):
    if mode == LibCfg.CREATE_MODE_AUTO:
      try_vlib = True
      try_alib = True
      fake = False
    elif mode == LibCfg.CREATE_MODE_VAMOS:
      try_vlib = True
      try_alib = False
      fake = False
    elif mode == LibCfg.CREATE_MODE_AMIGA:
      try_vlib = False
      try_alib = True
      fake = False
    elif mode == LibCfg.CREATE_MODE_FAKE:
      try_vlib = True
      try_alib = False
      fake = True
    else:
      raise ValueError("invalid lib mode: '%s'" % mode)
    return try_vlib, try_alib, fake

  def _check_version(self, name, addr, open_ver):
    # check version
    lib = Library(self.mem, addr)
    lib_ver = lib.version
    if lib_ver < open_ver:
      log_libmgr.warn("lib '%s' has too low version: %d < %d",
                      name, lib_ver, open_ver)
      return 0
    else:
      log_libmgr.info("lib '%s' version %d ok for open version %d",
                      name, lib_ver, open_ver)
      return addr