def Import(modid, modid1): global nofmod if modid1 == "SYSTEM": thismod = ThisModule(modid, modid1, True, key=0) # FIXME I added the 0 SPF nofmod -= 1 thismod.lev = 0 thismod.dsc = system thismod.rdo = True else: fname = MakeFileName(modid1, ".smb") R = Files.Old(fname) if R != None: # Files.Set(R, F, 0) Files.ReadInt(R) # discard. key = Files.ReadInt(R) modname = Files.ReadString(R) thismod = ThisModule(modid, modid1, True, key) thismod.rdo = True class_ = Read(R) # (*version key*) if class_ != versionkey: ORS.Mark("wrong version") class_ = Read(R) while class_ != 0: obj = Object() obj.class_ = class_ obj.name = Files.ReadString(R) obj.type_ = InType(R, thismod) obj.lev = -thismod.lev if class_ == Typ: t = obj.type_ t.typobj = obj k = Read( R ) # (*fixup bases of previously declared pointer types*) while k != 0: typtab[k].base = t k = Read(R) else: if class_ == Const: if obj.type_.form == Real: obj.val = Files.ReadInt(R) else: obj.val = Files.ReadNum(R) elif class_ == Var: obj.val = Files.ReadNum(R) obj.rdo = True obj.next = thismod.dsc thismod.dsc = obj class_ = Read(R) else: ORS.Mark("import not available")
def InType(R, thismod): ref = Read(R) if ref < 0: T = typtab[-ref] # (*already read*) else: t = Type() T = t typtab[ref] = t t.mno = thismod.lev form = Read(R) t.form = form if form == Pointer: t.base = InType(R, thismod) t.size = 4 elif form == Array: t.base = InType(R, thismod) t.len_ = Files.ReadNum(R, ) t.size = Files.ReadNum(R, ) elif form == Record: t.base = InType(R, thismod) if t.base.form == NoTyp: t.base = None obj = None else: obj = t.base.dsc t.len_ = Files.ReadNum(R) # (*TD adr/exno*) t.nofpar = Files.ReadNum(R) # (*ext level*) t.size = Files.ReadNum(R) class_ = Read(R) while class_ != 0: # (*fields*) fld = Object() fld.class_ = class_ fld.name = Files.ReadString(R) if fld.name[0] != 0x0: fld.expo = True fld.type_ = InType(R, thismod) else: fld.expo = False fld.type_ = nilType fld.val = Files.ReadNum(R) fld.next = obj obj = fld class_ = Read(R) t.dsc = obj elif form == Proc: t.base = InType(R, thismod) obj = None np = 0 class_ = Read(R) while class_ != 0: # (*parameters*) par = Object() par.class_ = class_ readonly = Read(R) par.rdo = readonly == 1 par.type_ = InType(R, thismod) par.next = obj obj = par np += 1 class_ = Read(R) t.dsc = obj t.nofpar = np t.size = 4 modname = Files.ReadString(R) if modname: # [0] != 0x0: # (*re-import*) key = Files.ReadInt(R) name = Files.ReadString(R) mod = ThisModule(modname, modname, False, key) obj = mod.dsc # (*search type*) while (obj != None) and (obj.name != name): obj = obj.next if obj != None: T = obj.type_ # (*type object found in object list of mod*) else: # (*insert new type object in object list of mod*) obj = Object() obj.name = name obj.class_ = Typ obj.next = mod.dsc mod.dsc = obj obj.type_ = t t.mno = mod.lev T = t typtab[ref] = T return T
def ThisMod(name): global root, AllocPtr res = 0 nofimps = 0 import_ = [None] * 16 mod = root while mod is not None and mod.name != name: mod = mod.next if mod == None: # (*load*) print 'loading:', name R = OpenFile(name) if R: ## Files.Set(R, F, 0) modname = Files.ReadString(R) key = Files.ReadInt(R) version = Files.ReadByte(R) size = Files.ReadInt(R) print 'Module', modname, key, version, size impname = Files.ReadString(R) while impname: impkey = Files.ReadInt(R) impmod = ThisMod(impname) import_[nofimps] = impmod impmod.refcnt += 1 nofimps += 1 impname = Files.ReadString(R) print 'Imports', import_ mod = Module(modname) mod.data = p = AllocPtr AllocPtr = (p + size + 0x10) / 0x20 * 0x20 mod.size = AllocPtr - p mod.num = 1 if root is None else (root.num + 1) mod.next = root root = mod p += DescSize mod.key = key SYSTEM.PUT(mod.num * 4 + MTOrg, p) # (*module table entry*) n = Files.ReadInt(R) print 'type_descriptors', n for _ in range(0, n, 4): w = Files.ReadInt(R) SYSTEM.PUT(p, w) p += 4 varsize = Files.ReadInt(R) assert varsize == (varsize / 4 * 4), repr(varsize) print 'varsize', varsize q = p + varsize while p < q: SYSTEM.PUT(p, 0) p += 4 strx = Files.ReadInt(R) print 'strings', strx for _ in range(strx): ch = Files.Read(R) SYSTEM.PUTBYTE(p, ch) p += 1 while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 mod.code = p code_length = Files.ReadInt(R) print 'code length', code_length for _ in range(0, code_length, 4): instruction = Files.ReadCode(R) # Foul hackery! SYSTEM.PUT(p, instruction) p += 4 mod.imp = p # (*copy imports*) for i, impmod in enumerate(import_): if impmod is not None: SYSTEM.PUT(p, impmod.data) p += 4 mod.cmd = p # (*commands*) ch = Files.Read(R) while ch: while ch: SYSTEM.PUTBYTE(p, ch) p += 1 ch = Files.Read(R) while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 n = Files.ReadInt(R) SYSTEM.PUT(p, n) p += 4 ch = Files.Read(R) while p % 4: SYSTEM.PUTBYTE(p, 0) p += 1 mod.ent = p # (*entries*) nofent = Files.ReadInt(R) for _ in range(nofent): w = Files.ReadInt(R) SYSTEM.PUT(p, w) p += 4 mod.ptr = p # (*pointer references*) w = Files.ReadInt(R) while w >= 0: SYSTEM.PUT(p, mod.data + w) p += 4 w = Files.ReadInt(R) SYSTEM.PUT(p, 0) p += 4 fixorgP = Files.ReadInt(R) fixorgD = Files.ReadInt(R) fixorgT = Files.ReadInt(R) w = Files.ReadInt(R) body = mod.code + w if Files.Read(R) != "O": raise ValueError print 'fixorgP', fixorgP print 'fixorgD', fixorgD print 'fixorgT', fixorgT print # (*fixup of BL*) adr = mod.code + fixorgP * 4 while adr != mod.code: inst = SYSTEM.GET(adr) mno = inst / 0x100000 % 0x10 pno = inst / 0x1000 % 0x100 disp = inst % 0x1000 impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) dest = SYSTEM.GET(impmod.ent + pno * 4) dest = dest + impmod.code offset = (dest - adr - 4) / 4 SYSTEM.PUT(adr, (offset % 0x1000000) + 0x0F7000000) adr = adr - disp * 4 # (*fixup of LDR/STR/ADD*) adr = mod.code + fixorgD * 4 while adr != mod.code: inst = SYSTEM.GET(adr) mno = inst / 0x100000 % 0x10 disp = inst % 0x1000 if not mno: # (*global*) SYSTEM.PUT(adr, (inst / 0x1000000 * 0x10 + MT) * 0x100000 + mod.num * 4) else: # (*import*) impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) v = impmod.num SYSTEM.PUT(adr, (inst / 0x1000000 * 0x10 + MT) * 0x100000 + v * 4) inst = SYSTEM.GET(adr + 4) vno = inst % 0x100 offset = SYSTEM.GET(impmod.ent + vno * 4) if (inst / 0x100) % 2: offset = offset + impmod.code - impmod.data SYSTEM.PUT(adr + 4, inst / 0x10000 * 0x10000 + offset) adr = adr - disp * 4 # (*fixup of type descriptors*) adr = mod.data + fixorgT * 4 while adr != mod.data: inst = SYSTEM.GET(adr) mno = inst / 0x1000000 % 0x10 vno = inst / 0x1000 % 0x1000 disp = inst % 0x1000 if not mno: # (*global*) inst = mod.data + vno else: # (*import*) impmod_data_addr = SYSTEM.GET(mod.imp + (mno - 1) * 4) impmod = look_up_module_by_data_addr(impmod_data_addr) offset = SYSTEM.GET(impmod.ent + vno * 4) inst = impmod.data + offset SYSTEM.PUT(adr, inst) adr = adr - disp * 4 return mod