Sigrid Solveig Haflínudóttirprint traceback if /config failed8da52652 years agoHistory
308 lines · 12.5 KB · Python
RawDownload
#!/usr/bin/env pythonfrom __future__ import print_functionimport timeimport sysimport readlineimport argparseimport numexprimport tracebackfrom scarelib import * parser = argparse.ArgumentParser(description="")parser.add_argument('-a', dest='arch', help='Target architecture')parser.add_argument('-c', dest='cpu', help='Target cpu')parser.add_argument('-f', dest='inFile', help='File to read')parser.add_argument('--base', type=lambda x: parseInt(x), dest='baseaddr', help='Base Address (default: 0x400000)')parser.add_argument('--stack', type=lambda x: parseInt(x), dest='stackaddr', help='Stack Address (default: 0x401000)')parser.add_argument('--memsize', dest='memsize', help='Emulator Memory Size (default: 0x800000 [8MB])') ## CommandscmdQuit = ["/exit", "/x", "/quit", "/q"]cmdHelp = ["/", "/help", "/?", "/h"]cmdConf = ["/config", "/c"]cmdPList= ["/list", "/l"] def parseInt(x):    return int(numexpr.evaluate(x).item()) # parseCmd# Commands must start with / to be parsed# If 0 is returned, the main command loop will not try to assemble the input# If 1 is returned, then the main command loop should try to assemble the input# If 2 is returned, the main command loop should not append the current command and just assemble and run# If 3 is returned, reinitialize the scaremudef parseCmd(cmd, smu):    shouldAssemble = 1    if len(cmd) > 0:      if cmd[0] == "/":        shouldAssemble = 0        cmdList = cmd.split()        cmdListLen = len(cmdList)         if cmdList[0] in cmdQuit:            sys.exit()         if cmdList[0] in cmdHelp:            print(helpfile)         if cmdList[0] in cmdConf:            if cmdListLen == 3 or cmdListLen == 4:                try:                    cfgOptName = cmdList[1]                    cfgOptVal = cmdList[2]                    cfgOptExtra = cmdList[3] if cmdListLen == 4 else ""                    if cfgOptName in sConfig.keys():                        third = ("/"+cfgOptExtra) if cfgOptExtra != "" else ""                        print(f"{cfgOptName}->{cfgOptVal}{third}")                        # TODO: Keep better track of config option types                        if cfgOptName == "emu/arch":                            okArch = cfgOptVal in archez.keys()                            if okArch:                                arch = archez[cfgOptVal]                                if cfgOptExtra in arch["cpus"].keys():                                    sConfig[cfgOptName] = cfgOptVal                                    sConfig["emu/cpu"] = cfgOptExtra                                else:                                    print(f"Invalid cpu! Supported cpus: {arch["cpus"].keys()}")                            else:                                print(f"Invalid arch! Supported arches: {archez.keys()}")                        else:                            sConfig[cfgOptName] = parseInt(cfgOptVal)                    else:                        print("Invalid config opt name!")                except Exception as e:                    print(f"Error in /config:")                    print(traceback.format_exc())            elif cmdListLen == 2:                try:                    cfgOptName = cmdList[1]                    if cfgOptName in sConfig.keys():                        print(f"{cfgOptName} = {sConfig[cfgOptName]}")                except Exception as e:                    print(f"Error in /config:")                    print(traceback.format_exc())            else:                configPrint(sConfig)         if cmdList[0] == "/info":            if smu:                smu.info()            else:                print("No emulator running!")         if cmdList[0] == "/regs":            if smu:                smu.printRegs()            else:                print("No emulator running!")         if cmdList[0] == "/back":            backAmount = parseInt(cmdList[1])            if backAmount <= len(smu.asm_code):                smu.asm_code = smu.asm_code[:-backAmount]                print(f"Moved back {backAmount} lines to line {len(smu.asm_code)}")                shouldAssemble = 2 # Reassemble and run            else:                print(f"Too far back! You're currently on line {len(smu.asm_code)}")         if cmdList[0] == "/load":            if cmdListLen > 1:                smu.asm_code = loadAsm(cmdList[1], lambda c: parseCmd(c, smu))                currentAddr = sConfig["emu/baseaddr"]            else:                print("Please specify a filename!")         if cmdList[0] == "/save":            if cmdListLen > 1:                saveAsm(smu.asm_code, cmdList[1])            else:                print("Please specify a filename!")         if cmdList[0] == "/run":            shouldAssemble = 2 # Reassemble and run         if cmdList[0] == "/reset":            shouldAssemble = 3 # Reinitialize          if cmdList[0] in cmdPList:            printListing(smu, smu.asm_code, plan9=("plan9" in cmdList))         if cmdList[0] == "/read":            if cmdListLen >= 3 and cmdListLen <= 4:                try:                    memout = 0                    baseAddr = 0                    if cmdList[1][0] == "$":                        regTarget = cmdList[1].split("$")[1]                        regValue = smu.readReg(regTarget)                        if regValue is not None:                            memout = smu.mu_ctx.mem_read(regValue, parseInt(cmdList[2]))                            baseAddr = regValue                    else:                        baseAddr = parseInt(cmdList[1])                        memout = smu.mu_ctx.mem_read(baseAddr, parseInt(cmdList[2]))                    if memout:                        if cmdListLen > 3:                            with open(cmdList[3], "wb") as f:                                f.truncate()                                f.write(memout)                        else:                            dHex(memout, baseAddr)                    else:                        print("Usage: /read {0xaddress|$register} size")                except Exception as e:                    print(e)                    print("Usage: /read {0xaddress|$register} size")            else:                print("Usage: /read {0xaddress|$register} size")         if cmdList[0] == "/write":            if cmdListLen == 3:                try:                    if cmdList[2][0] == '.':                        with open(cmdList[2], "rb") as f:                            data = f.read(-1)                            print(f"{cmdList[2]}: {len(data)} bytes")                    else:                        data = bytes.fromhex(cmdList[2])                    if cmdList[1][0] == "$":                        regTarget = cmdList[1].split("$")[1]                        regValue = smu.readReg(regTarget)                        if regValue is not None:                            smu.mu_ctx.mem_write(regValue, data)                    else:                        memout = smu.mu_ctx.mem_write(parseInt(cmdList[1]), data)                except Exception as e:                    print(e)                    print("Usage: /write {0xaddress|$register} hexdata")            else:                print("Usage: /write {0xaddress|$register} hexdata")         if cmdList[0] == "/set":            if cmdListLen == 3:                try:                    regTarget = cmdList[1]                    value = parseInt(cmdList[2])                    smu.writeReg(regTarget, value)                except Exception as e:                    print(e)                    print("Usage: /set register value")            else:                print("Usage: /set register value")         if cmdList[0] == "/get":            if cmdListLen >= 2:                try:                    for regTarget in cmdList[1:]:                        value = smu.readReg(regTarget)                        print(f"{cRegN} {regTarget}: {value:032x}")                except Exception as e:                    print(e)                    print("Usage: /get register [register... ]")            else:                print("Usage: /get register [register... ]")         if cmdList[0] == "/dis":            try:                if cmdListLen == 3:                    if cmdList[1][0:2] == "0x":                        instructions4dis = smu.dis(parseInt(cmdList[1]), parseInt(cmdList[2]))                        printListing(smu, instructions4dis)                    elif cmdList[1][0] == "$":                        regTarget = cmdList[1].split("$")[1]                        regValue = smu.readReg(regTarget)                        if regValue is not None:                            instructions4dis = smu.dis(regValue, parseInt(cmdList[2]))                            printListing(smu, instructions4dis)                    else:                        print("Usage: /dis {0xaddress|$register} size")                else:                    print("Usage: /dis {0xaddress|$register} size")            except Exception as e:                print(e)                print("Usage: /dis {0xaddress|$register} size")         if cmdList[0] == "/export":            try:                if cmdListLen == 3:                    fArch = smu.arch_name                    if cmdList[1] == "bin":                        mcLen = len(smu.machine_code)                        if mcLen > 0:                            print(f"Exporting {mcLen} bytes of code as raw binary")                            exportBin(smu.machine_code, "bin", fArch, cmdList[2])                        else:                            print("No machine code to export!")                    elif cmdList[1] == "elf64":                        mcLen = len(smu.machine_code)                        if mcLen > 0:                            print(f"Exporting {mcLen} bytes of code as ELF64")                            exportBin(smu.machine_code, "elf64", fArch, cmdList[2])                        else:                            print("No machine code to export!")                    else:                        print("Invalid binary type!")                else:                    print("Usage: /export type filename")            except Exception as e:                print(f"Export Error: {e}")    else:        shouldAssemble = 0 # Don't do anything if there's no input     return shouldAssemble if __name__ == '__main__':    args = parser.parse_args()    print("Type / for help\n")    inFile = args.inFile if args.inFile else ""    currentArch = args.arch.lower() if args.arch else "NoArch"    currentCpu = args.cpu.lower() if args.cpu else ""    if args.stackaddr:        sConfig["emu/stackaddr"] = args.stackaddr    if args.baseaddr:        sConfig["emu/baseaddr"] = args.baseaddr    if args.memsize:        sConfig["emu/memsize"] = args.memsize       if currentArch == "NoArch":        print(f"Please select an architecture! Use `/c emu/arch ARCH`.\nSupported arches: {archez.keys()}")        smu = False        currentAddr = sConfig["emu/baseaddr"]    else:        sConfig["emu/arch"] = currentArch        sConfig["emu/cpu"] = currentCpu        smu = scaremu(currentArch, currentCpu)        currentAddr = sConfig["emu/baseaddr"]        if inFile:            smu.asm_code = loadAsm(inFile, lambda c: parseCmd(c, smu))    printSplash()    while True:        try:            cmd = input(f"[{cArchP}{currentArch}]{cIP}{currentAddr:02x}{cEnd}> ")            try:                shouldAsm = parseCmd(cmd, smu)            except:                continue            if    (((smu == False) and (sConfig["emu/arch"] != "NoArch")) or                   sConfig["emu/arch"] != currentArch or                   shouldAsm == 3):                currentArch = sConfig["emu/arch"]                currentCpu = sConfig["emu/cpu"]                currentAddr = sConfig["emu/baseaddr"]                smu = scaremu(currentArch, currentCpu)            if smu != False and shouldAsm:                if shouldAsm == 1:                    smu.asm_code.append(cmd)                if len(smu.asm_code) > 0:                    asmStatus = smu.asm(smu.asm_code)                    if asmStatus == 0:                        currentAddr, runStatus = smu.run()                        if runStatus == 0:                            smu.printRegs()                        else:                            print("run() returned a non-zero value")                    else:                        smu.asm_code.pop() # Gets rid of the last line of assembly                else:                    currentAddr = sConfig["emu/baseaddr"]        except EOFError:            break

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t