Ejemplo n.º 1
0
  def close_lib(self, addr, ctx):
    # get lib object
    if addr not in self.open_libs_addr:
      self.lib_log("close_lib","No library found at address %06x" % (addr))
      return None
    lib = self.open_libs_addr[addr]

    # native lib handling
    if lib.is_native:
      tr = Trampoline(ctx,"close_lib[%s]" % lib.name)
      self._close_native_lib(lib, ctx, tr)
      if lib.ref_cnt == 0:
        self._free_native_lib(lib, ctx, tr)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")
      tr.final_rts()
      tr.done()

    # own lib handling
    else:
      # decrement usage
      lib.dec_usage()
      # not used any more
      if lib.ref_cnt == 0:
        # finally close lib
        self._unregister_open_lib(lib)
        self._free_vamos_lib(lib, ctx)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")

    return lib
Ejemplo n.º 2
0
    def __init__(self, width, height):
        Level.__init__(self, width, height)
        ##initialize blocks##
        boxtop = Terrain(20, -19, 40, 2, 0, 0, 100, self, 0.5)
        boxleft = Terrain(-1, -5, 2, 30, 0, 0, 100, self, 0.5)
        boxbottom = Terrain(20, 9, 40, 2, 0, 0, 100, self, 0.5)
        boxright = Terrain(41, -5, 2, 30, 0, 0, 100, self, 0.5)
        barrbottom = Terrain(15, -6, 6, 1, 0, 0, 100, self, .5)
        barrright = Terrain(18.5, -11, 1, 10, 0, 0, 100, self, .5)

        goal = Goal(38, -15.5, 1, 5, 0, 0, 100, self, 0.5)

        tramp1 = Trampoline(7, 7, 6, 1, 0, 0, 100, self, .5)
        tramp2 = Trampoline(36, 7, 6, 1, 0, 0, 100, self, .5)
        tramp3 = Trampoline(32, -8, 6, 1, 0, 0, 100, self, .5)
        tramp4 = Trampoline(36, -23, 6, 1, 0, 0, 100, self, .5)
        p = Player(2, 5, 1, 2, 0, 0, 1, self, 0.5)
        g = GoalBlock(16.5, -7, 2, 2, 0, 0, 2, self, 0.5)
        self.add_elem(p)
        self.add_elem(barrbottom)
        self.add_elem(barrright)
        self.add_elem(tramp1)
        self.add_elem(tramp2)
        self.add_elem(tramp3)
        self.add_elem(tramp4)
        self.add_elem(g)
        self.add_elem(boxtop)
        self.add_elem(boxright)
        self.add_elem(boxbottom)
        self.add_elem(boxleft)
        self.add_elem(goal)
Ejemplo n.º 3
0
    def __init__(self, width, height):
        Level.__init__(self, width, height)
        ##initialize blocks##
        boxtop = Terrain(20, -19, 40, 2, 0, 0,100, self, 0.5)
        boxleft= Terrain(-1,-5,2,30,0,0,100,self,0.5)
        boxbottom= Terrain(27.0,9.0,54.0,2.0,0.0,0.0,100,self,0.5)
        boxright= Terrain(55,-5,2,30,0,0,100,self,0.5)

        goal= Goal(53,5,1,5,0,0,100,self,0.5)
        
        
        b =   Block(2, 2,  4, 1, 0, 0,  1, self, 0.5)
        c =  Player(7, 5,  1, 2, 0, 0,  1, self, 0.5)
        d =   Block(4, 2, 4, 1, 0, 5,  2, self, 0.5)  
        a =   GoalBlock(4, 5, 2, 2, 0, 5,  2, self, 0.5) 
        m = Trampoline(30, -4, 2, 1, 0, 0, 1, self, 0.5)
        e = Spike(30.0, 7.5, 41.0, 1.0, 0.0, 0.0, 100, self, 0.1)
        f = Spike(29.0, 6.5, 1.0, 1.0, 0.0, 0.0, 100, self, 0.1)
        self.add_elem(c)
        self.add_elem(m)
        self.add_elem(b)
        self.add_elem(a)
        self.add_elem(d)
        self.add_elem(e)
        self.add_elem(f)
        self.add_elem(boxtop)
        self.add_elem(boxright)
        self.add_elem(boxbottom)
        self.add_elem(boxleft)
        self.add_elem(goal)
Ejemplo n.º 4
0
  def close_lib(self, addr, ctx):
    # get lib object
    if addr not in self.open_libs_addr:
      self.lib_log("close_lib","No library found at address %06x" % (addr))
      return None
    lib = self.open_libs_addr[addr]
    lib.open_base_addr = addr
    self.lib_log("close_lib","Closing %s at address %06x" % (lib.name,addr))

    # native lib handling
    if lib.is_native:
      tr = Trampoline(ctx,"close_lib[%s]" % lib.name)
      self._close_native_lib(lib, addr, ctx, tr)
      if lib.ref_cnt == 0:
        pass
        # THOR: Do not release the library memory. Problem is that
        # the SAS/C go leaves references to strings to its library
        # segment pending in the QUAD: file, which then become
        # invalid if the library is removed. In reality, we should
        # only flush libs if we are low on memory.
        #  self._free_native_lib(lib, ctx, tr)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")
      tr.final_rts()
      tr.done()

    # own lib handling
    else:
      # decrement usage
      lib.dec_usage()
      # not used any more
      if lib.ref_cnt == 0:
        # finally close lib
        pass
        #self._unregister_open_lib(lib,None)
        #self._free_vamos_lib(lib, ctx)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")

    return lib
Ejemplo n.º 5
0
  def close_lib(self, addr, ctx):
    # get lib object
    if addr not in self.open_libs_addr:
      self.lib_log("close_lib","No library found at address %06x" % (addr))
      return None
    lib = self.open_libs_addr[addr]

    # native lib handling
    if lib.is_native:
      tr = Trampoline(ctx,"close_lib[%s]" % lib.name)
      self._close_native_lib(lib, ctx, tr)
      if lib.ref_cnt == 0:
        self._free_native_lib(lib, ctx, tr)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")
      tr.final_rts()
      tr.done()

    # own lib handling
    else:
      # decrement usage
      lib.dec_usage()
      # not used any more
      if lib.ref_cnt == 0:
        # finally close lib
        self._unregister_open_lib(lib)
        self._free_vamos_lib(lib, ctx)
      elif lib.ref_cnt < 0:
        raise VamosInternalError("CloseLib: invalid ref count?!")

    return lib
Ejemplo n.º 6
0
 def _close_native_lib(self, lib, lib_base, ctx):
   self.lib_log("close_lib","closing native lib: '%s' ref_cnt: %d" % (lib.name, lib.ref_cnt))
   tr = Trampoline(ctx,"close_lib[%s]" % lib.name)
   self._close_native_lib_int(lib, lib_base, ctx, tr)
   if lib.ref_cnt == 0:
     # lib has no users and can be expunged/removed
     expunge_mode = lib.config.expunge
     if expunge_mode == 'last_close':
       self.lib_log("close_lib","expunging native lib: '%s'" % lib.name)
       # do it now
       self._free_native_lib(lib, ctx, tr)
   elif lib.ref_cnt < 0:
     raise VamosInternalError("CloseLib: invalid ref count?!")
   tr.final_rts()
   tr.done()
Ejemplo n.º 7
0
    def _load_and_open_native_lib(self, name, sane_name, lib_cfg, ctx):
        """try to load and open native lib
       return new lib instance or None if lib was not found"""

        # create empty lib
        lib = AmigaLibrary(sane_name, LibraryStruct, lib_cfg)

        # determine file name from open_name, i.e. prepend LIBS: if no path is found
        load_name = self._get_load_lib_name(name)
        self.lib_log("load_lib",
                     "trying to load amiga lib: '%s'" % load_name,
                     level=logging.INFO)

        # pick current dir lock if available
        # this allows to resolve relative paths given in load_name
        cur_dir_lock = None
        proc = ctx.process
        if proc is not None:
            cur_dir_lock = proc.cwd_lock

        # map ami path of lib to sys_path
        sys_path = ctx.path_mgr.ami_to_sys_path(cur_dir_lock,
                                                load_name,
                                                searchMulti=True)

        # is native lib available in file system?
        if sys_path and os.path.exists(sys_path):
            self.lib_log("load_lib", "found amiga lib: '%s'" % load_name)

            # setup trampoline
            tr = Trampoline(ctx, "create_lib[%s]" % sane_name)
            self._create_native_lib(lib, sys_path, ctx, tr)
            self._open_native_lib_int(lib, ctx, tr)
            tr.final_rts()
            tr.done()

            # do we have an optional fd file for this lib?
            lib.fd = self._load_fd(sane_name)

            self._register_lib_name(lib)

            return lib
        else:
            return None
Ejemplo n.º 8
0
    def close_lib(self, addr, ctx):
        # get lib object
        if addr not in self.open_libs_addr:
            self.lib_log("close_lib",
                         "No library found at address %06x" % (addr))
            return None
        lib = self.open_libs_addr[addr]
        lib.open_base_addr = addr
        self.lib_log("close_lib",
                     "Closing %s at address %06x" % (lib.name, addr))

        # native lib handling
        if lib.is_native:
            tr = Trampoline(ctx, "close_lib[%s]" % lib.name)
            self._close_native_lib(lib, addr, ctx, tr)
            if lib.ref_cnt == 0:
                pass
                # THOR: Do not release the library memory. Problem is that
                # the SAS/C go leaves references to strings to its library
                # segment pending in the QUAD: file, which then become
                # invalid if the library is removed. In reality, we should
                # only flush libs if we are low on memory.
                #  self._free_native_lib(lib, ctx, tr)
            elif lib.ref_cnt < 0:
                raise VamosInternalError("CloseLib: invalid ref count?!")
            tr.final_rts()
            tr.done()

        # own lib handling
        else:
            # decrement usage
            lib.dec_usage()
            # not used any more
            if lib.ref_cnt == 0:
                # finally close lib
                self._unregister_open_lib(lib, None)
                self._free_vamos_lib(lib, ctx)
            elif lib.ref_cnt < 0:
                raise VamosInternalError("CloseLib: invalid ref count?!")

        return lib
Ejemplo n.º 9
0
  def open_lib(self, name, ver, ctx):
    """open a new library in memory
       return new AmigaLibrary instance that is setup or None if lib was not found

       Note: may prepare a trampoline to finish operation!
    """
    # sanitize lib name
    sane_name = self._get_sane_lib_name(name)

    # is lib already opened?
    if sane_name in self.open_libs_name:
      self.lib_log("open_lib","opening already open lib: %s" % sane_name)
      lib = self.open_libs_name[sane_name]
      if lib.is_native:
        # call Open()
        tr = Trampoline(ctx,"open_lib[%s]" % sane_name)
        self._open_native_lib(lib, ctx, tr)
        tr.final_rts()
        tr.done()
      else:
        # handle usage count
        lib.inc_usage()

    # lib has to be openend
    else:

      # first check if its an internal vamos library
      if sane_name in self.vamos_libs:
        self.lib_log("open_lib","opening vamos lib: %s" % sane_name)
        lib = self.vamos_libs[sane_name]
        is_vamos_lib = True
      # otherwise create a new and empty AmigaLibrary
      else:
        self.lib_log("open_lib","create default lib: %s" % sane_name)
        lib_cfg = self.cfg.get_lib_config(sane_name)
        lib = AmigaLibrary(sane_name, LibraryDef, lib_cfg)
        is_vamos_lib = False

      # dump config of lib
      self._dump_lib_cfg(lib.config)

      # is lib mode = 'off' then reject open
      mode = lib.config.mode
      if mode == 'off':
        self.lib_log("open_lib","reject open: mode='off': %s" % sane_name, level=logging.WARN)
        return None

      # try to load an fd file for this lib
      lib.fd = self._load_fd(sane_name)

      # is native loading allowed?
      native_loaded = False
      native_allowed = mode in ('auto','amiga')
      if native_allowed:
        # now check if the library has a native counterpart
        # if yes then create memory layout with it
        load_name = self._get_load_lib_name(name)
        if ctx.seg_loader.can_load_seg(None,load_name,local_path=True):
          # setup trampoline
          tr = Trampoline(ctx,"create_lib[%s]" % sane_name)
          self._create_native_lib(lib, load_name, ctx, tr)
          self._open_native_lib(lib, ctx, tr)
          tr.final_rts()
          tr.done()
          native_loaded = True

      # no native lib available...
      # either its a vamos lib or we auto create one from an FD file
      if not native_loaded:
        # we need to have an FD file otherwise we can't create lib
        if lib.fd == None:
          self.lib_log("create_lib","can't create auto lib without FD file: %s" % sane_name, level=logging.ERROR)
          return None

        # if not 'auto' or 'vamos' then fail now
        if mode == 'amiga':
          self.lib_log("open_lib","can't open amiga lib: %s" % sane_name, level=logging.WARN)
          return None

        # create a (opt. fake/empty) vamos library
        self._create_vamos_lib(lib, ctx)
        self._register_open_lib(lib,None)
        lib.inc_usage()

    self.lib_log("open_lib","leaving open_lib(): %s -> %06x" % (lib,lib.addr_base_open), level=logging.DEBUG)
    return lib
Ejemplo n.º 10
0
 def run_command(self,start_pc,argsptr,arglen,stacksize):
   newstack     = self.alloc.alloc_memory("shell command stack",stacksize)
   newstackbase = newstack.addr
   newstacktop  = newstackbase + stacksize
   oldstackbase = self.process.this_task.access.r_s("pr_Task.tc_SPLower");
   oldstacktop  = self.process.this_task.access.r_s("pr_Task.tc_SPUpper");
   old_stackptr = self.cpu.r_reg(REG_A7) # addr of sys call return
   # put stack size on top of stack
   self.mem.w32(newstacktop - 4,stacksize)
   # activate new stack
   new_stackptr = newstacktop - 8
   self.process.this_task.access.w_s("pr_Task.tc_SPLower",newstackbase)
   self.process.this_task.access.w_s("pr_Task.tc_SPUpper",newstacktop)
   # NOTE: the Manx fexec and BPCL mess is not (yet) setup here.
   # setup trampoline to enter sub process
   tr = Trampoline(self, "RunCommand")
   # reserve a long for old stack
   old_stack_off = tr.dc_l(0)
   # code starts
   tr.save_all_but_d0()
   # new proc registers: d0=arg_len a0=arg_cptr
   tr.set_dx_l(0, arglen)
   tr.set_ax_l(0, argsptr)
   # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
   # various C programs rely on it being present (1.3-3.1 at least have it).
   tr.set_dx_l(2, stacksize)
   # to track old dos values
   odg = self.mem_map.get_old_dos_guard_base()
   tr.set_ax_l(2, odg)
   tr.set_ax_l(5, odg)
   tr.set_ax_l(6, odg)
   # save old stack and set new stack
   tr.write_ax_l(7, old_stack_off, True) # write to data offset (dc.l above)
   tr.set_ax_l(7, new_stackptr)
   # call code! (jmp - return value is on stack)
   tr.jmp(start_pc)
   # restore stack (set a label to return from new stack - see below)
   return_off = tr.get_code_offset()
   tr.read_ax_l(7, old_stack_off, True) # read from data offset (dc.l above)
   # restore regs
   tr.restore_all_but_d0()
   # keep the old input file handle
   input_fh = self.process.get_input()
   # trap to clean up sub process resources
   def trap_stop_run_command():
     ret_code = self.cpu.r_reg(REG_D0)
     log_proc.info("return from RunCommand: ret_code=%d", ret_code)
     self.cpu.w_reg(REG_A7,old_stackptr)
     self.process.this_task.access.w_s("pr_Task.tc_SPLower",oldstackbase)
     self.process.this_task.access.w_s("pr_Task.tc_SPUpper",oldstacktop)
     self.alloc.free_memory(newstack)
     input_fh.setbuf("")
     # The return code remains in d0 as is
   tr.final_rts(trap_stop_run_command)
   # realize trampoline in memory (data+code)
   tr.done()
   # get label addr -> set as return value of new stack
   return_addr = tr.get_code_addr(return_off)
   log_proc.debug("new_stack=%06x return_addr=%06x", new_stackptr, return_addr)
   # place return address for new process
   self.mem.w32(new_stackptr, return_addr)
Ejemplo n.º 11
0
  def start_sub_process(self, proc):
    log_proc.info("start sub process: %s", proc)
    self.proc_list.append(proc)
    self._set_this_task(proc)

    # setup trampoline to enter sub process
    tr = Trampoline(self, "SubProcJump")
    # reserve a long for old stack
    old_stack_off = tr.dc_l(0)
    # code starts
    tr.save_all_but_d0()
    # new proc registers: d0=arg_len a0=arg_cptr
    tr.set_dx_l(0, proc.arg_len)
    tr.set_ax_l(0, proc.arg_base)
    # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
    # various C programs rely on it being present (1.3-3.1 at least have it).
    tr.set_dx_l(2, proc.stack_size)
    # to track old dos values
    odg = self.mem_map.get_old_dos_guard_base()
    tr.set_ax_l(2, odg)
    tr.set_ax_l(5, odg)
    tr.set_ax_l(6, odg)
    # save old stack and set new stack
    tr.write_ax_l(7, old_stack_off, True) # write to data offset (dc.l above)
    new_stack = proc.stack_initial
    tr.set_ax_l(7, new_stack)
    # call code! (jmp - return value is on stack)
    tr.jmp(proc.prog_start)
    # restore stack (set a label to return from new stack - see below)
    return_off = tr.get_code_offset()
    tr.read_ax_l(7, old_stack_off, True) # read from data offset (dc.l above)
    # restore regs
    tr.restore_all_but_d0()
    # trap to clean up sub process resources
    def trap_stop_sub_process():
      self.stop_sub_process()
    tr.final_rts(trap_stop_sub_process)
    # realize trampoline in memory (data+code)
    tr.done()
    # get label addr -> set as return value of new stack
    return_addr = tr.get_code_addr(return_off)
    log_proc.debug("new_stack=%06x return_addr=%06x", new_stack, return_addr)
    # place return address for new process
    self.mem.w32(new_stack, return_addr)
Ejemplo n.º 12
0
    def run_shell(self, start_pc, packet, stacksize, trap_stop_handler):
        newstack = self.alloc.alloc_memory("shell command stack", stacksize)
        newstackbase = newstack.addr
        newstacktop = newstackbase + stacksize
        oldstackbase = self.process.this_task.access.r_s("pr_Task.tc_SPLower")
        oldstacktop = self.process.this_task.access.r_s("pr_Task.tc_SPUpper")
        old_stackptr = self.cpu.r_reg(REG_A7)  # addr of sys call return
        # put stack size on top of stack
        self.mem.access.w32(newstacktop - 4, stacksize)
        # activate new stack
        new_stackptr = newstacktop - 4
        self.process.this_task.access.w_s("pr_Task.tc_SPLower", newstackbase)
        self.process.this_task.access.w_s("pr_Task.tc_SPUpper", newstacktop)
        # NOTE: the Manx fexec and BPCL mess is not (yet) setup here.
        # setup trampoline to enter sub process
        tr = Trampoline(self, "RunCommand")
        # reserve a long for old stack
        old_stack_off = tr.dc_l(0)
        # code starts
        tr.save_all_but_d0()
        # new proc registers: d1=packet
        tr.set_dx_l(1, packet >> 2)
        # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
        # various C programs rely on it being present (1.3-3.1 at least have it).
        tr.set_dx_l(2, stacksize)
        # to track old dos values
        tr.set_ax_l(2, self.dos_guard_base)
        tr.set_ax_l(5, self.dos_guard_base)
        tr.set_ax_l(6, self.dos_guard_base)
        # save old stack and set new stack
        tr.write_ax_l(7, old_stack_off,
                      True)  # write to data offset (dc.l above)
        tr.set_ax_l(7, new_stackptr)
        # call code! (jmp - return value is on stack)
        tr.jmp(start_pc)
        # restore stack (set a label to return from new stack - see below)
        return_off = tr.get_code_offset()
        tr.read_ax_l(7, old_stack_off,
                     True)  # read from data offset (dc.l above)
        # restore regs
        tr.restore_all_but_d0()

        def trap_stop_function():
            ret_code = self.cpu.r_reg(REG_D0)
            log_proc.info("return from SystemTagList: ret_code=%d", ret_code)
            self.cpu.w_reg(REG_A7, old_stackptr)
            self.process.this_task.access.w_s("pr_Task.tc_SPLower",
                                              oldstackbase)
            self.process.this_task.access.w_s("pr_Task.tc_SPUpper",
                                              oldstacktop)
            self.alloc.free_memory(newstack)
            trap_stop_handler(ret_code)

        tr.final_rts(trap_stop_function)
        # realize trampoline in memory (data+code)
        tr.done()
        # get label addr -> set as return value of new stack
        return_addr = tr.get_code_addr(return_off)
        log_proc.debug("new_stack=%06x return_addr=%06x", new_stackptr,
                       return_addr)
        # place return address for new process
        self.mem.access.w32(new_stackptr, return_addr)
Ejemplo n.º 13
0
  def start_sub_process(self, proc):
    log_proc.info("start sub process: %s", proc)
    self.proc_list.append(proc)
    self._set_this_task(proc)

    # setup trampoline to enter sub process
    tr = Trampoline(self, "SubProcJump")

    # reserve a long for old stack
    old_stack_off = tr.dc_l(0)

    # code starts
    tr.save_all_but_d0()
    # new proc registers: d0=arg_len a0=arg_cptr
    tr.set_dx_l(0, proc.arg_len)
    tr.set_ax_l(0, proc.arg_base)
    # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
    # various C programs rely on it being present (1.3-3.1 at least have it).
    tr.set_dx_l(2, proc.stack_size)
    # to track old dos values
    tr.set_ax_l(2, self.dos_guard_base)
    tr.set_ax_l(5, self.dos_guard_base)
    tr.set_ax_l(6, self.dos_guard_base)
    # save old stack and set new stack
    tr.write_ax_l(7, old_stack_off, True) # write to data offset (dc.l above)
    new_stack = proc.stack_initial
    tr.set_ax_l(7, new_stack)
    # call code! (jmp - return value is on stack)
    tr.jmp(proc.prog_start)
    # restore stack (set a label to return from new stack - see below)
    return_off = tr.get_code_offset()
    tr.read_ax_l(7, old_stack_off, True) # read from data offset (dc.l above)
    # restore regs
    tr.restore_all_but_d0()
    # trap to clean up sub process resources
    def trap_stop_sub_process():
      self.stop_sub_process()
    tr.final_rts(trap_stop_sub_process)
    # realize trampoline in memory (data+code)
    tr.done()
    # get label addr -> set as return value of new stack
    return_addr = tr.get_code_addr(return_off)
    log_proc.debug("new_stack=%06x return_addr=%06x", new_stack, return_addr)
    # place return address for new process
    self.mem.access.w32(new_stack, return_addr)
Ejemplo n.º 14
0
  def open_lib(self, name, ver, ctx):
    """open a new library in memory
       return new AmigaLibrary instance that is setup or None if lib was not found

       Note: may prepare a trampoline to finish operation!
    """
    # sanitize lib name
    sane_name = self._get_sane_lib_name(name)

    # is lib already opened?
    if sane_name in self.open_libs_name:
      self.lib_log("open_lib","opening already open lib: %s" % sane_name)
      lib = self.open_libs_name[sane_name]
      if lib.is_native:
        # call Open()
        tr = Trampoline(ctx,"open_lib[%s]" % sane_name)
        self._open_native_lib(lib, ctx, tr)
        tr.final_rts()
        tr.done()
      else:
        # handle usage count
        lib.inc_usage()

    # lib has to be openend
    else:

      # first check if its an internal vamos library
      if sane_name in self.vamos_libs:
        self.lib_log("open_lib","opening vamos lib: %s" % sane_name)
        lib = self.vamos_libs[sane_name]
        is_vamos_lib = True
      # otherwise create a new and empty AmigaLibrary
      else:
        self.lib_log("open_lib","create default lib: %s" % sane_name)
        lib_cfg = self.cfg.get_lib_config(sane_name)
        lib = AmigaLibrary(sane_name, LibraryDef, lib_cfg)
        is_vamos_lib = False

      # dump config of lib
      self._dump_lib_cfg(lib.config)

      # is lib mode = 'off' then reject open
      mode = lib.config.mode
      if mode == 'off':
        self.lib_log("open_lib","reject open: mode='off': %s" % sane_name, level=logging.WARN)
        return None

      # try to load an fd file for this lib
      lib.fd = self._load_fd(sane_name)

      # is native loading allowed?
      native_loaded = False
      native_allowed = mode in ('auto','amiga')
      if native_allowed:
        # now check if the library has a native counterpart
        # if yes then create memory layout with it
        load_name = self._get_load_lib_name(name)
        if ctx.seg_loader.can_load_seg(None,load_name):
          # setup trampoline
          tr = Trampoline(ctx,"create_lib[%s]" % sane_name)
          self._create_native_lib(lib, load_name, ctx, tr)
          self._open_native_lib(lib, ctx, tr)
          tr.final_rts()
          tr.done()
          native_loaded = True

      # no native lib available...
      # either its a vamos lib or we auto create one from an FD file
      if not native_loaded:
        # we need to have an FD file otherwise we can't create lib
        if lib.fd == None:
          self.lib_log("create_lib","can't create auto lib without FD file: %s" % sane_name, level=logging.ERROR)
          return None

        # if not 'auto' or 'vamos' then fail now
        if mode == 'amiga':
          self.lib_log("open_lib","can't open amiga lib: %s" % sane_name, level=logging.WARN)
          return None

        # create a (opt. fake/empty) vamos library
        self._create_vamos_lib(lib, ctx)
        self._register_open_lib(lib)
        lib.inc_usage()

    self.lib_log("open_lib","leaving open_lib(): %s" % lib, level=logging.DEBUG)
    return lib
Ejemplo n.º 15
0
 def _open_native_lib(self, lib, ctx):
   # call Open()
   tr = Trampoline(ctx,"open_lib[%s]" % sane_name)
   self._open_native_lib_int(lib, ctx, tr)
   tr.final_rts()
   tr.done()
Ejemplo n.º 16
0
 def init_trampoline(self):
   self.tr_mem_size = 256
   self.tr_mem = self.alloc.alloc_memory("Trampoline", self.tr_mem_size)
   self.tr = Trampoline(self, self.tr_mem)
Ejemplo n.º 17
0
 def _expunge_native_lib(self, lib, ctx):
   self.lib_log("expunge", "expunging native lib: '%s'" % lib.name)
   tr = Trampoline(ctx,"expunge_lib[%s]" % lib.name)
   self._free_native_lib(lib, ctx, tr)
   tr.final_rts()
   tr.done()
Ejemplo n.º 18
0
 def start_sub_process(self, proc):
   log_proc.info("start sub process: %s", proc)
   self.proc_list.append(proc)
   self._set_this_task(proc)
   
   # setup trampoline to enter sub process
   tr_mem_size = 128
   tr_mem = self.alloc.alloc_memory("SubProcJump", tr_mem_size)
   tr = Trampoline(self, tr_mem)
   tr.init()
   tr.save_all_but_d0()
   # new proc registers: d0=arg_len a0=arg_cptr
   tr.set_dx_l(0, proc.arg_len)
   tr.set_ax_l(0, proc.arg_base)
   # to track old dos values
   tr.set_ax_l(2, self.dos_guard_base)
   tr.set_ax_l(5, self.dos_guard_base)
   tr.set_ax_l(6, self.dos_guard_base)
   # setup new stack
   stack_save_addr = tr_mem.addr + tr_mem_size - 4
   tr.write_ax_l(7, stack_save_addr)
   new_stack = proc.stack_initial
   tr.set_ax_l(7, new_stack)
   # call code! (jmp - return value is on stack)
   tr.jmp(proc.prog_start)
   # restore stack (set a label to return from new stack - see below)
   lab = tr.set_label()
   tr.read_ax_l(7, stack_save_addr)
   # restore regs
   tr.restore_all_but_d0()
   # trap to clean up sub process resources
   tr.trap(lambda x : self.stop_sub_process())
   tr.rts()
   tr.done()
   # get label addr -> set as return value of new stack
   lab_addr = tr.get_label(lab)
   log_proc.debug("new_stack=%06x trampoline_return=%06x", new_stack, lab_addr)
   self.mem.access.w32(new_stack, lab_addr)
   
   # push trampoline
   self.tr_list.append(tr)
Ejemplo n.º 19
0
 def run_shell(self,start_pc,packet,stacksize,trap_stop_handler):
   newstack     = self.alloc.alloc_memory("shell command stack",stacksize)
   newstackbase = newstack.addr
   newstacktop  = newstackbase + stacksize
   oldstackbase = self.process.this_task.access.r_s("pr_Task.tc_SPLower");
   oldstacktop  = self.process.this_task.access.r_s("pr_Task.tc_SPUpper");
   old_stackptr = self.cpu.r_reg(REG_A7) # addr of sys call return
   # put stack size on top of stack
   self.mem.access.w32(newstacktop - 4,stacksize)
   # activate new stack
   new_stackptr = newstacktop - 8
   self.process.this_task.access.w_s("pr_Task.tc_SPLower",newstackbase)
   self.process.this_task.access.w_s("pr_Task.tc_SPUpper",newstacktop)
   # NOTE: the Manx fexec and BPCL mess is not (yet) setup here.
   # setup trampoline to enter sub process
   tr = Trampoline(self, "RunCommand")
   # reserve a long for old stack
   old_stack_off = tr.dc_l(0)
   # code starts
   tr.save_all_but_d0()
   # new proc registers: d1=packet
   tr.set_dx_l(1, packet >> 2)
   # d2=stack_size.  this value is also in 4(sp) (see Process.init_stack), but
   # various C programs rely on it being present (1.3-3.1 at least have it).
   tr.set_dx_l(2, stacksize)
   # to track old dos values
   tr.set_ax_l(2, self.dos_guard_base)
   tr.set_ax_l(5, self.dos_guard_base)
   tr.set_ax_l(6, self.dos_guard_base)
   # save old stack and set new stack
   tr.write_ax_l(7, old_stack_off, True) # write to data offset (dc.l above)
   tr.set_ax_l(7, new_stackptr)
   # call code! (jmp - return value is on stack)
   tr.jmp(start_pc)
   # restore stack (set a label to return from new stack - see below)
   return_off = tr.get_code_offset()
   tr.read_ax_l(7, old_stack_off, True) # read from data offset (dc.l above)
   # restore regs
   tr.restore_all_but_d0()
   def trap_stop_function():
     ret_code = self.cpu.r_reg(REG_D0)
     log_proc.info("return from SystemTagList: ret_code=%d", ret_code)
     self.cpu.w_reg(REG_A7,old_stackptr)
     self.process.this_task.access.w_s("pr_Task.tc_SPLower",oldstackbase)
     self.process.this_task.access.w_s("pr_Task.tc_SPUpper",oldstacktop)
     self.alloc.free_memory(newstack)
     trap_stop_handler(ret_code)
   tr.final_rts(trap_stop_function)
   # realize trampoline in memory (data+code)
   tr.done()
   # get label addr -> set as return value of new stack
   return_addr = tr.get_code_addr(return_off)
   log_proc.debug("new_stack=%06x return_addr=%06x", new_stackptr, return_addr)
   # place return address for new process
   self.mem.access.w32(new_stackptr, return_addr)