Example #1
0
        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
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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
        }
Example #5
0
        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
        }
Example #6
0
        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));
        }
Example #7
0
        private NeoChunk Compile(ChunkNode ast)
        {
            var compiler = new BytecodeCompiler(ast);

            return(BuildNeoChunk(compiler.Compile()));
        }
Example #8
0
        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));
            }
        }
Example #10
0
        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);
        }
Example #11
0
        // Compiling.

        public static LuaPrototype Compile(TextWriter errorWriter, TextReader sourceReader, string sourceName)
        {
            return(BytecodeCompiler.Compile(errorWriter, sourceReader, sourceName));
        }