public void MOV_Bonanza32() { var programText = new string[] { "section .text", "global _start", "_start:", "mov eax, 0x11112222 ; eax = 0x11112222", "mov ax, 0x3333 ; eax = 0x11113333 (works, only low 16 bits changed)", "mov al, 0x44 ; eax = 0x11113344 (works, only low 8 bits changed)", "mov ah, 0x55 ; eax = 0x11115544 (works, only high 8 bits changed)", "xor ah, ah ; eax = 0x11110044 (works, only high 8 bits cleared)", "mov eax, 0x11112222 ; eax = 0x11112222", "xor al, al ; eax = 0x11112200 (works, only low 8 bits cleared)", "mov eax, 0x11112222 ; eax = 0x11112222", "xor ax, ax ; eax = 0x11110000 (works, only low 16 bits cleared)" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11113333, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11113344, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11115544, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11110044, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112200, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11112222, agent.ReadExtendedRegister(Register.EAX)); // Program should have terminated on the second tick ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0x11110000, agent.ReadExtendedRegister(Register.EAX)); // Program should have terminated on the second tick }
public void CompileReadKeyboardAsm() { var compiler = new BytecodeCompiler <UInt32>(); var sourceFileName = "./../../../../picovm/asm-src/read-keyboard32.asm"; Xunit.Assert.True(File.Exists(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)), $"Cannot find file {sourceFileName} for test, current directory: {System.Environment.CurrentDirectory}"); var compilation = compiler.Compile(sourceFileName); Xunit.Assert.Equal(0, compilation.Errors.Count); }
public void CompileHelloWorldLinux64Asm() { var compiler = new BytecodeCompiler <UInt64>(); var sourceFileName = "./../../../../picovm/asm-src/hello-world-linux64.asm"; Xunit.Assert.True(File.Exists(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)), $"Cannot find file {sourceFileName} for test, current directory: {System.Environment.CurrentDirectory}"); var compilation = compiler.Compile(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)); Xunit.Assert.Equal(0, compilation.Errors.Count); }
public void MOV_REG_CON_Overlayed() { var programText = new string[] { "section .text", "global _start", "_start:", "MOV EAX, 4294967295", // copy the value 11111111111111111111111111111111 into eax "MOV AX, 0", // copy the value 0000000000000000 into ax "MOV AH, 170", // copy the value 10101010 (0xAA) into ah "MOV AL, 85", // copy the value 01010101 (0x55) into al "MOV EAX, 0", // copy the value 11111111111111111111111111111111 into eax "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFFFFF, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((ushort)0xFFFF, agent.ReadRegister(Register.AX)); Xunit.Assert.Equal((byte)0xFF, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((byte)0xFF, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFF0000, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)0, agent.ReadRegister(Register.AX)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFAA00, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)170, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)0, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0xFFFFAA55, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal((uint)170, agent.ReadHalfRegister(Register.AH)); Xunit.Assert.Equal((uint)85, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)0, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }
public void PUSH_POP_Overlayed() { var programText = new string[] { "section .text", "global _start", "_start:", "PUSH 4294945365", // push the value 1111 1111 1111 1111 1010 1010 0101 0101 (FFFF AA55) onto the stack "POP EAX", // pop it back into eax "PUSH 2863315917", // push the value 1010 1010 1010 1010 1011 1011 1100 1101 (AAAA BBCD) onto the stack "POP EAX", // pop it back into eax "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); Xunit.Assert.Equal((uint)65535, agent.StackPointer); var ret = agent.Tick(); // PUSH 4294945365 Xunit.Assert.Null(ret); agent.Dump(); Xunit.Assert.Equal((uint)(65535 - 4), agent.StackPointer); Xunit.Assert.Equal(4294945365, agent.StackPeek32()); Xunit.Assert.Equal((uint)0, agent.ReadExtendedRegister(Register.EAX)); // POP EAX #1 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535), agent.StackPointer); Xunit.Assert.Equal((uint)4294945365, agent.ReadExtendedRegister(Register.EAX)); // PUSH 2863315917 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535 - 4), agent.StackPointer); Xunit.Assert.Equal(2863315917, agent.StackPeek32()); Xunit.Assert.Equal((uint)4294945365, agent.ReadExtendedRegister(Register.EAX)); // POP EAX #2 ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((uint)(65535), agent.StackPointer); Xunit.Assert.Equal((uint)2863315917, agent.ReadExtendedRegister(Register.EAX)); // END ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }
public void MOV_Bonanza64() { var programText = new string[] { "section .text", "global _start", "_start:", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "mov eax, 0x55556666 ; actual: rax = 0x0000000055556666", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "mov ax, 0x7777 ; rax = 0x1111222233337777 (works!)", "mov rax, 0x1111222233334444 ; rax = 0x1111222233334444", "xor eax, eax ; actual: rax = 0x0000000000000000", " ; again, it wiped whole register" }; var compiler = new BytecodeCompiler <UInt64>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent64(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x0000000055556666, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233337777, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x1111222233334444, agent.ReadR64Register(Register.RAX)); ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal((ulong)0x0000000000000000, agent.ReadR64Register(Register.RAX)); }
private NeoChunk Compile(ChunkNode ast) { var compiler = new BytecodeCompiler(ast); return(BuildNeoChunk(compiler.Compile())); }
public void MOV_REG_CON_Simple() { var programText = new string[] { "section .text", "global _start", "_start:", " MOV EAX, 4294967295 ; copy the value 11111111111111111111111111111111 into eax", " MOV AX, 0 ; copy the value 0000000000000000 into ax", " MOV AH, 170 ; copy the value 10101010 (0xAA) into ah", " MOV AL, 85 ; copy the value 01010101 (0x55) into al", " MOV EBX, 5 ; copy the value 5 into ebx", " MOV EAX, EBX ; copy the value in ebx into eax", " PUSH 4 ; push 4 on the stack", " PUSH EAX ; push eax (5) on the stack", " PUSH 6 ; push 6 on the stack", " POP EBX ; pop stack (6) into ebx", " POP EBX ; pop stack (5) into ebx", " POP [EBX] ; pop stack (4) into [ebx] memory location = 5", " ADD [EBX], 10 ; add 10 to the value in [ebx] which would change 4 to 14", " PUSH [EBX] ; push [ebx] memory location=5 value=14 onto the stack", "END" }; var compiler = new BytecodeCompiler <UInt32>(); var compiled = compiler.Compile(programText, "UNIT_TEST"); var agent = new Agent(kernel, compiled.TextSegment, 0); var ret = agent.Tick(); Xunit.Assert.Null(ret); Xunit.Assert.Equal(4294967295, agent.ReadExtendedRegister(Register.EAX)); ret = agent.Tick(); Xunit.Assert.Equal(0U, agent.ReadRegister(Register.AX)); ret = agent.Tick(); Xunit.Assert.Equal(170, agent.ReadHalfRegister(Register.AH)); ret = agent.Tick(); Xunit.Assert.Equal(85, agent.ReadHalfRegister(Register.AL)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EAX)); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); Xunit.Assert.Equal(6U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); Xunit.Assert.Equal(5U, agent.ReadExtendedRegister(Register.EBX)); ret = agent.Tick(); ret = agent.Tick(); ret = agent.Tick(); Xunit.Assert.NotNull(ret); Xunit.Assert.Equal(0, ret); // Program should have terminated on the second tick }
public void ReadKeyboardAsm64() { // http://www.sco.com/developers/devspecs/gabi41.pdf var compiler = new BytecodeCompiler <UInt64>(); var sourceFileName = "./../../../../picovm/asm-src/read-keyboard64.asm"; Xunit.Assert.True(File.Exists(Path.Combine(System.Environment.CurrentDirectory, sourceFileName)), $"Cannot find file {sourceFileName} for test, current directory: {System.Environment.CurrentDirectory}"); var compilationInterface = compiler.Compile(sourceFileName); Xunit.Assert.Equal(0, compilationInterface.Errors.Count); Xunit.Assert.IsType <CompilationResult64>(compilationInterface); var compilation = (CompilationResult64)compilationInterface; var packager = new PackagerElf64(compilation); // Test ELF file header write/read/compare fidelity var header = packager.GenerateElfFileHeader(); { var ms = new MemoryStream(); header.Write(ms, 1, 1); ms.Seek(0, SeekOrigin.Begin); var header2 = new Header64(); header2.Read(ms); Xunit.Assert.Equal(header.EI_CLASS, header2.EI_CLASS); Xunit.Assert.Equal(header.EI_DATA, header2.EI_DATA); Xunit.Assert.Equal(header.EI_VERSION, header2.EI_VERSION); Xunit.Assert.Equal(header.E_TYPE, header2.E_TYPE); Xunit.Assert.Equal(header.E_MACHINE, header2.E_MACHINE); Xunit.Assert.Equal(header.E_VERSION, header2.E_VERSION); Xunit.Assert.Equal(header.E_ENTRY, header2.E_ENTRY); Xunit.Assert.Equal(header.E_PHOFF, header2.E_PHOFF); Xunit.Assert.Equal(header.E_SHOFF, header2.E_SHOFF); Xunit.Assert.Equal(header.E_FLAGS, header2.E_FLAGS); Xunit.Assert.Equal(header.E_EHSIZE, header2.E_EHSIZE); Xunit.Assert.Equal(header.E_PHENTSIZE, header2.E_PHENTSIZE); Xunit.Assert.Equal(header.E_PHNUM, header2.E_PHNUM); Xunit.Assert.Equal(header.E_SHENTSIZE, header2.E_SHENTSIZE); Xunit.Assert.Equal(header.E_SHNUM, header2.E_SHNUM); Xunit.Assert.Equal(header.E_SHSTRNDX, header2.E_SHSTRNDX); } // Test program header write/read/compare fidelity { var ms = new MemoryStream(); var ph = packager.GenerateProgramHeader64(); ph.Write(ms); ms.Seek(0, SeekOrigin.Begin); var ph2 = new ProgramHeader64(); ph2.Read(ms); Xunit.Assert.Equal(ph.P_TYPE, ph2.P_TYPE); Xunit.Assert.Equal(ph.P_OFFSET, ph2.P_OFFSET); Xunit.Assert.Equal(ph.P_VADDR, ph2.P_VADDR); Xunit.Assert.Equal(ph.P_PADDR, ph2.P_PADDR); Xunit.Assert.Equal(ph.P_FILESZ, ph2.P_FILESZ); Xunit.Assert.Equal(ph.P_MEMSZ, ph2.P_MEMSZ); Xunit.Assert.Equal(ph.P_FLAGS, ph2.P_FLAGS); Xunit.Assert.Equal(ph.P_ALIGN, ph2.P_ALIGN); } // Test full package/load/compare fidelity { var ms = new MemoryStream(); packager.Write(ms); ms.Seek(0, SeekOrigin.Begin); var loader = new LoaderElf64(ms); var compilation2 = loader.LoadImage(); Xunit.Assert.NotNull(compilation2); Xunit.Assert.Equal(compilation.EntryPoint.Value, compilation2.EntryPoint); Xunit.Assert.Equal(AssemblerPackageOutputType.Elf64, Packager.Inspector.DetectPackageOutputType(ms)); } }
static ICompilationResult Assemble(string output, AssemblerPackageOutputType outputType, string format, string input) { if (!System.IO.File.Exists(input)) { return(CompilationResultBase.Error($"Source input file {input} not found.")); } if (System.IO.File.Exists(output)) { Console.Error.WriteLine($"Executable output file {output} already exists."); // DEBUG System.IO.File.Delete(output); //return -4; } // Compile. ICompilationResult compilation; { Console.Out.WriteLine($"Compiling source file: {input}"); IBytecodeCompiler?compiler = null; switch (outputType) { case AssemblerPackageOutputType.Elf32: Console.Out.WriteLine($"Packaging bytecode as: {Enum.GetName(typeof(AssemblerPackageOutputType), outputType)}"); compiler = new BytecodeCompiler <UInt32>(); break; case AssemblerPackageOutputType.Elf64: Console.Out.WriteLine($"Packaging bytecode as: {Enum.GetName(typeof(AssemblerPackageOutputType), outputType)}"); compiler = new BytecodeCompiler <UInt64>(); break; default: Console.Error.WriteLine($"Unsupported assembler output type {outputType}."); System.Environment.Exit(-5); return(null); } compilation = compiler.Compile(input); if (compilation.Errors.Count > 0) { Console.Error.WriteLine($"Compilation failed with {compilation.Errors.Count} errors."); return(compilation); } } // Package. IPackager packager; using (var fs = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.SequentialScan)) { switch (outputType) { case AssemblerPackageOutputType.AOut32: packager = new PackagerAOut32((CompilationResult32)compilation); packager.Write(fs); break; case AssemblerPackageOutputType.Elf32: packager = new PackagerElf32((CompilationResult32)compilation); packager.Write(fs); break; case AssemblerPackageOutputType.Elf64: packager = new PackagerElf64((CompilationResult64)compilation); packager.Write(fs); break; default: throw new InvalidOperationException($"Unknown packaging format: {outputType}"); } fs.Flush(); fs.Close(); } return(compilation); }
// Compiling. public static LuaPrototype Compile(TextWriter errorWriter, TextReader sourceReader, string sourceName) { return(BytecodeCompiler.Compile(errorWriter, sourceReader, sourceName)); }