Example #1
0
 public static Process SpawnProcess(string filename, string arguments, bool wait,
                                    StandardOutputCallback standardOut)
 {
     return(SpawnProcess(
                filename,
                arguments,
                wait,
                standardOut,
                standardOut));
 }
Example #2
0
 public static Process SpawnProcess(string filename, string arguments, bool wait,
                                    StandardOutputCallback standardOut,
                                    StandardOutputCallback errorOut)
 {
     return(SpawnProcess(
                filename,
                new FileInfo(filename).Directory.FullName,
                arguments,
                wait,
                standardOut,
                errorOut));
 }
Example #3
0
    public ICompilerOutput <Solution> Compile(Solution solution, StandardOutputCallback standardOutput)
    {
        /*This is only temporary code until we have an actual build config system*/
        string finalOutput = solution.BuildDirectory + "\\disk.iso";

        if (File.Exists(finalOutput))
        {
            File.Delete(finalOutput);
        }
        string bootsect = "";
        StandardCompileOutput <Solution> output = new StandardCompileOutput <Solution>(finalOutput, solution);

        foreach (Project p in solution.Projects)
        {
            ICompilerOutput <Project> projOut = CompileProject(p, standardOutput);
            foreach (ICompileOutputEntry e in projOut.Errors)
            {
                output.addError(
                    e.File,
                    e.Line,
                    e.Column,
                    e.Message);
            }
            foreach (ICompileOutputEntry w in projOut.Warnings)
            {
                output.addWarning(
                    w.File,
                    w.Line,
                    w.Column,
                    w.Message);
            }

            if (projOut.Errors.Length != 0)
            {
                continue;
            }
            bootsect = projOut.OutputFile;
        }

        if (File.Exists(bootsect))
        {
            generateISO(
                "OS Test",
                bootsect,
                solution.BuildDirectory + "\\disk",
                finalOutput,
                standardOutput,
                new string[0]);
        }

        return(output);
    }
Example #4
0
    public static Process SpawnProcess(string filename, string currentDirectory, string arguments, bool wait,
                                       StandardOutputCallback standardOut,
                                       StandardOutputCallback errorOut)
    {
        //standardOut(filename + " " + arguments);

        //create the process with redirecting output enabled
        Process process = new Process()
        {
            StartInfo = new ProcessStartInfo()
            {
                FileName         = filename,
                WorkingDirectory = currentDirectory,
                Arguments        = arguments,

                RedirectStandardError  = true,
                RedirectStandardOutput = true,

                UseShellExecute = false,
                CreateNoWindow  = true
            }
        };

        process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) {
            if (e.Data == null)
            {
                return;
            }
            standardOut(e.Data);
        };
        process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) {
            if (e.Data == null)
            {
                return;
            }
            errorOut(e.Data);
        };

        //start the process
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        //wait for the process to finish
        if (wait)
        {
            process.WaitForExit();
        }
        return(process);
    }
Example #5
0
    public ICompilerOutput<Solution> Compile(Solution solution, StandardOutputCallback standardOutput)
    {
        /*This is only temporary code until we have an actual build config system*/
        string finalOutput = solution.BuildDirectory + "\\disk.iso";
        if (File.Exists(finalOutput)) { File.Delete(finalOutput); }
        string bootsect = "";
        StandardCompileOutput<Solution> output = new StandardCompileOutput<Solution>(finalOutput, solution);

        foreach (Project p in solution.Projects) {
            ICompilerOutput<Project> projOut = CompileProject(p, standardOutput);
            foreach (ICompileOutputEntry e in projOut.Errors) {
                output.addError(
                    e.File,
                    e.Line,
                    e.Column,
                    e.Message);
            }
            foreach (ICompileOutputEntry w in projOut.Warnings) {
                output.addWarning(
                    w.File,
                    w.Line,
                    w.Column,
                    w.Message);
            }

            if (projOut.Errors.Length != 0) { continue; }
            bootsect = projOut.OutputFile;
        }

        if (File.Exists(bootsect)) {
            generateISO(
                "OS Test",
                bootsect,
                solution.BuildDirectory + "\\disk",
                finalOutput,
                standardOutput,
                new string[0]);
        }

        return output;
    }
Example #6
0
    private void link(ref outputEntry[] errors, ref outputEntry[] warnings, string[] files, string outputFile, StandardOutputCallback stdOut)
    {
        //define the filename for the linker
        string linker = new FileInfo("compilers/linker/ld.exe").FullName;
        //linker = "C:\\cygwin\\bin\\ld.exe";

        //define the arguments to pass to the linker
        string args = "-m elf_i386 -o \"" + outputFile + "\" "; //-m elf_i386
        for (int c = 0; c < files.Length; c++) {
            args += "\"" + files[c] + "\" ";
        }

        //invoke the linker
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            linker,
            null,
            args,
            true,
            delegate(string line) {
                stdOut(line);
                gnuStdOutHandler(ref e, ref w, "/linker/ld", line);
            });

        //clean up
        errors = e;
        warnings = w;
    }
Example #7
0
    private void link(string[] files, string outputFile, StandardCompileOutput<Project> output, StandardOutputCallback stdOut)
    {
        //perform the link
        outputEntry[] errors = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        link(ref errors, ref warnings, files, outputFile, stdOut);

        //add the errors and warnings to the output object
        for (int c = 0; c < errors.Length; c++) {
            output.addError(null, 0, 0, errors[c].message);
        }
        for (int c = 0; c < warnings.Length; c++) {
            output.addWarning(null, 0, 0, warnings[c].message);
        }
    }
Example #8
0
    private void generateISO(string volumeTitle, string bootsector, string diskContents, string output, StandardOutputCallback stdOut, string[] hideFiles)
    {
        if (!Directory.Exists(diskContents)) {
            Directory.CreateDirectory(diskContents);
        }

        //define the path for the mkisofs (make iso filesystem) exe
        string mkisofs = new FileInfo("compilers/mkisofs/mkisofs.exe").FullName;

        //define the arguments to pass to the exe
        string[] args = new string[] {
            "-iso-level 3",
            "-v -allow-lowercase",
            "-volid \"" + volumeTitle + "\"",
            "-o \"" + output + "\"",
        };
        if (bootsector != null) {
            if (!File.Exists(bootsector)) { return; }
            File.Copy(bootsector, diskContents + "\\bootsect.bin", true);
            int sectorCount = (int)Math.Ceiling(new FileInfo(bootsector).Length * 1.0f / 512);
            Helpers.AddObject(ref args, "-b bootsect.bin");
            Helpers.AddObject(ref args, "-no-emul-boot -boot-load-size " + sectorCount);
            Helpers.AddObject(ref hideFiles, "bootsect.bin");
        }

        //write the arguments for the hidden files
        string hideArgsBuffer = "-hide ";
        for (int c = 0; c < hideFiles.Length; c++) {
            hideArgsBuffer += "" + hideFiles[c] + " ";
        }
        Helpers.AddObject(ref args, hideArgsBuffer);

        //add disk contents folder
        Helpers.AddObject(ref args, "\"" + diskContents + "\"");

        //invoke the exe
        Helpers.SpawnProcess(
            mkisofs,
            new FileInfo(mkisofs).Directory.FullName,
            Helpers.Flatten(args, " "),
            true,
            stdOut);

        //clean up
        if (bootsector != null) {
            File.Delete(diskContents + "\\bootsect.bin");
        }
    }
Example #9
0
    private void compileC(ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut)
    {
        //get the filename for the GCC compiler
        string gcc = new FileInfo("compilers/gcc/bin/gcc.exe").FullName;

        //invoke the GCC compiler
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            gcc,
            null,
            "-c \"" + filename + "\" -o \"" + outputFile + "\" " +
            "-Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m32",
            true,
            delegate(string line) {
                stdOut(line);
                gnuStdOutHandler(ref e, ref w, filename, line);
            });

        //clean up
        errors = e;
        warnings = w;
    }
Example #10
0
    private void compileC(string outputFile, StandardCompileOutput<Project> output, fileObj[] codeFiles, fileObj[] headerFiles, StandardOutputCallback stdOut)
    {
        if (File.Exists(outputFile)) { File.Delete(outputFile); }

        //collapse the code files and header files into one array but add the header files first.
        fileObj[] files = new fileObj[0];
        Helpers.AddObject(ref files, headerFiles);
        Helpers.AddObject(ref files, codeFiles);

        //flatten the files down to a single file
        string collapsed = collapseFiles(files, ".c");

        //perform the compile
        outputEntry[] errors = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        compileC(ref errors, ref warnings, collapsed, outputFile, stdOut);
        processCompileResults(codeFiles, output, errors, warnings);

        //clean up
        File.Delete(collapsed);
    }
Example #11
0
    private void compileAssembly(bool linkable, ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut)
    {
        //define the filename for the NASM compiler
        string nasmCompiler = new FileInfo("compilers/nasm/nasm.exe").FullName;

        //call nasm to compile the ASM code.
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            nasmCompiler,
            new FileInfo(filename).Directory.FullName,
            (linkable ? "-f elf32 " : "") +
            "\"" + filename + "\" " +
            "-o \"" + outputFile + "\"",
            true,
            delegate(string line) {
                stdOut(line);
                gnuStdOutHandler(
                    ref e,
                    ref w,
                    filename,
                    line);
            });

        //clean up
        errors = e;
        warnings = w;
    }
Example #12
0
    private void link(ref outputEntry[] errors, ref outputEntry[] warnings, string[] files, string outputFile, StandardOutputCallback stdOut)
    {
        //define the filename for the linker
        string linker = new FileInfo("compilers/linker/ld.exe").FullName;
        //linker = "C:\\cygwin\\bin\\ld.exe";

        //define the arguments to pass to the linker
        string args = "-m elf_i386 -o \"" + outputFile + "\" "; //-m elf_i386

        for (int c = 0; c < files.Length; c++)
        {
            args += "\"" + files[c] + "\" ";
        }

        //invoke the linker
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            linker,
            null,
            args,
            true,
            delegate(string line) {
            stdOut(line);
            gnuStdOutHandler(ref e, ref w, "/linker/ld", line);
        });

        //clean up
        errors   = e;
        warnings = w;
    }
Example #13
0
    public void Start(int memory, StandardOutputCallback standardOutput)
    {
        //already running?
        if (Running)
        {
            return;
        }

        #region Invoke Qemu
        string qemuArguments = "-qmp tcp:127.0.0.1:4444,server,nowait " +
                               "-cdrom \"" + new FileInfo(p_DiskImage).FullName + "\" " +
                               "-m " + memory;

        //create a processlink process so that if this process is killed
        //it automatically kills the emulator as well.
        standardOutput("Launching process linker...");
        if (!File.Exists("processlink.exe"))
        {
            standardOutput("  Error! ProcessLink.exe is not found!");
            return;
        }
        p_Process = new Process()
        {
            StartInfo = new ProcessStartInfo {
                FileName  = "processLink.exe",
                Arguments = "-id " + Process.GetCurrentProcess().Id + " " +
                            "-f \"" + new FileInfo("emulators/qemu/qemu.exe").FullName + "\" " +
                            "-a " + qemuArguments,
                UseShellExecute        = false,
                CreateNoWindow         = true,
                RedirectStandardOutput = true
            }
        };

        //get the qemu process id from the spawn process
        int qemuPID = -1;
        p_Process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) {
            if (e.Data == null || qemuPID != -1)
            {
                return;
            }
            qemuPID = Convert.ToInt32(e.Data);
        };

        //launch the process
        standardOutput("Starting Qemu...");
        p_Process.Start();
        standardOutput("   Process linker PID=" + p_Process.Id);
        p_Process.BeginOutputReadLine();

        //wait until the spawner has launched Qemu
        while (qemuPID == -1)
        {
            ;
        }
        p_QemuProcess = Process.GetProcessById(qemuPID);
        standardOutput("   Started, PID=" + qemuPID);

        #endregion

        //connect to the Qemu Monitor
        p_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        int connectStart = Environment.TickCount;
        standardOutput("Connecting to Qemu's QMP service...");
        while (Environment.TickCount < connectStart + 1000)
        {
            try {
                p_Socket.Connect("localhost", 4444);
                p_Stream = new NetworkStream(p_Socket, true);
                break;
            }
            catch { }
        }

        //timed out?
        if (!p_Socket.Connected)
        {
            standardOutput("Error! Unable to connect to Qemu's QMP service");
            Stop();
            return;
        }

        //get the initial response from the server
        standardOutput("Performing handshake with QMP Server");
        JSONObject handshake = JSONObject.Decode("", monitorRead())[0];
        handshake = (JSONObject)handshake["QMP"];

        //get the version of the qemu emulator
        JSONObject version = (JSONObject)handshake["version"];
        version = (JSONObject)version["qemu"];
        int versionMajor = Convert.ToInt32(version["major"]);
        int versionMinor = Convert.ToInt32(version["minor"]);

        //enter command mode
        monitorWrite("{ \"execute\": \"qmp_capabilities\" }");
        JSONObject result = JSONObject.Decode(monitorRead())[0];
        result = (JSONObject)result["return"];
        if (result.ChildValues[0].ChildCount > 0)
        {
            standardOutput("Unable to enter into QMP Command mode!");
            Stop();
            return;
        }

        //create an event listener
        standardOutput("Starting event listener...");
        Thread eventListener = new Thread(new ThreadStart(delegate {
            while (Running)
            {
                //send a blank signal to the server so we don't interfere
                //with current messages.
                Monitor.Enter(p_SyncLock);
                monitorExecute("", null);
                monitorReadObject(false);
                Monitor.Exit(p_SyncLock);

                Thread.Sleep(100);
            }
        }));
        eventListener.Start();
        standardOutput("  Listening...");

        //success
        standardOutput("Qemu Emulator version " + versionMajor + "." + versionMinor);
        standardOutput("Qemu Emulator ready...");

        return;

        EmulationProcessor ps = GetProcessors()[0];
        while (true)
        {
            int time = Environment.TickCount;
            GetRegisters(ps);
            Console.WriteLine((Environment.TickCount - time) + "ms");
        }

        new DebugRegisters(this).Show();
    }
Example #14
0
    private void generateISO(string volumeTitle, string bootsector, string diskContents, string output, StandardOutputCallback stdOut, string[] hideFiles)
    {
        if (!Directory.Exists(diskContents))
        {
            Directory.CreateDirectory(diskContents);
        }

        //define the path for the mkisofs (make iso filesystem) exe
        string mkisofs = new FileInfo("compilers/mkisofs/mkisofs.exe").FullName;

        //define the arguments to pass to the exe
        string[] args = new string[] {
            "-iso-level 3",
            "-v -allow-lowercase",
            "-volid \"" + volumeTitle + "\"",
            "-o \"" + output + "\"",
        };
        if (bootsector != null)
        {
            if (!File.Exists(bootsector))
            {
                return;
            }
            File.Copy(bootsector, diskContents + "\\bootsect.bin", true);
            int sectorCount = (int)Math.Ceiling(new FileInfo(bootsector).Length * 1.0f / 512);
            Helpers.AddObject(ref args, "-b bootsect.bin");
            Helpers.AddObject(ref args, "-no-emul-boot -boot-load-size " + sectorCount);
            Helpers.AddObject(ref hideFiles, "bootsect.bin");
        }

        //write the arguments for the hidden files
        string hideArgsBuffer = "-hide ";

        for (int c = 0; c < hideFiles.Length; c++)
        {
            hideArgsBuffer += "" + hideFiles[c] + " ";
        }
        Helpers.AddObject(ref args, hideArgsBuffer);

        //add disk contents folder
        Helpers.AddObject(ref args, "\"" + diskContents + "\"");

        //invoke the exe
        Helpers.SpawnProcess(
            mkisofs,
            new FileInfo(mkisofs).Directory.FullName,
            Helpers.Flatten(args, " "),
            true,
            stdOut);

        //clean up
        if (bootsector != null)
        {
            File.Delete(diskContents + "\\bootsect.bin");
        }
    }
Example #15
0
    private void compileC(ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut)
    {
        //get the filename for the GCC compiler
        string gcc = new FileInfo("compilers/gcc/bin/gcc.exe").FullName;

        //invoke the GCC compiler
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            gcc,
            null,
            "-c \"" + filename + "\" -o \"" + outputFile + "\" " +
            "-Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m32",
            true,
            delegate(string line) {
            stdOut(line);
            gnuStdOutHandler(ref e, ref w, filename, line);
        });

        //clean up
        errors   = e;
        warnings = w;
    }
Example #16
0
    private void compileC(string outputFile, StandardCompileOutput <Project> output, fileObj[] codeFiles, fileObj[] headerFiles, StandardOutputCallback stdOut)
    {
        if (File.Exists(outputFile))
        {
            File.Delete(outputFile);
        }

        //collapse the code files and header files into one array but add the header files first.
        fileObj[] files = new fileObj[0];
        Helpers.AddObject(ref files, headerFiles);
        Helpers.AddObject(ref files, codeFiles);

        //flatten the files down to a single file
        string collapsed = collapseFiles(files, ".c");

        //perform the compile
        outputEntry[] errors   = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        compileC(ref errors, ref warnings, collapsed, outputFile, stdOut);
        processCompileResults(codeFiles, output, errors, warnings);

        //clean up
        File.Delete(collapsed);
    }
Example #17
0
    private void compileAssembly(bool linkable, ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut)
    {
        //define the filename for the NASM compiler
        string nasmCompiler = new FileInfo("compilers/nasm/nasm.exe").FullName;

        //call nasm to compile the ASM code.
        outputEntry[] e = errors;
        outputEntry[] w = warnings;
        Helpers.SpawnProcess(
            nasmCompiler,
            new FileInfo(filename).Directory.FullName,
            (linkable ? "-f elf32 " : "") +
            "\"" + filename + "\" " +
            "-o \"" + outputFile + "\"",
            true,
            delegate(string line) {
            stdOut(line);
            gnuStdOutHandler(
                ref e,
                ref w,
                filename,
                line);
        });

        //clean up
        errors   = e;
        warnings = w;
    }
Example #18
0
    private void compileAssembly(bool linkable, string outputFile, StandardCompileOutput <Project> output, fileObj[] files, StandardOutputCallback stdOut)
    {
        if (File.Exists(outputFile))
        {
            File.Delete(outputFile);
        }

        //collapse all the files into one file to compile
        string collapsed = collapseFiles(files, ".asm");

        //compile
        outputEntry[] errors   = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        compileAssembly(linkable, ref errors, ref warnings, collapsed, outputFile, stdOut);
        processCompileResults(files, output, errors, warnings);

        //clean up
        File.Delete(collapsed);
    }
Example #19
0
    public ICompilerOutput<Project> CompileProject(Project project, StandardOutputCallback standardOutput)
    {
        #region split up every file in the project into a code file

        fileObj[] assemblyFiles = new fileObj[0];
        fileObj[] cCodeFiles = new fileObj[0];
        fileObj[] cHeaderFiles = new fileObj[0];

        project.Root.Enumerate(true, delegate(ProjectEntity e) {
            if (!(e is ProjectFile)) { return true; }

            //add the filename into the appropriate code file list
            ProjectFile file = (ProjectFile)e;
            string ext = file.Extension.ToLower();
            switch (ext) {
                case ".c":
                    Helpers.AddObject(ref cCodeFiles, new fileObj(file));
                    break;
                case ".h":
                    Helpers.AddObject(ref cHeaderFiles, new fileObj(file));
                    break;
                case ".asm":
                    Helpers.AddObject(ref assemblyFiles, new fileObj(file));
                    break;
            }
            return true;
        });
        #endregion

        //define the final output file
        string finalOutput = getOuputFilename(project, "build.bin");
        StandardCompileOutput<Project> output = new StandardCompileOutput<Project>(finalOutput, project);
        string[] outputFiles = new string[0];
        if (File.Exists(finalOutput)) { File.Delete(finalOutput); }

        //define whether or not the assembly code should
        //be linked (no point in linking if theres nothing
        //to link with)
        bool linkable = cCodeFiles.Length != 0 || cHeaderFiles.Length != 0;

        //compile the assembly
        if (assemblyFiles.Length != 0) {
            //make sure that the main entry point assembly file is at the top
            //of the list to be compiled first.
            int bootfileIndex = -1;
            for (int c = 0; c < assemblyFiles.Length; c++) {
                if (assemblyFiles[c].ProjectFile.Name.ToLower() == "boot.asm") {
                    bootfileIndex = c;
                    break;
                }
            }
            if (bootfileIndex != -1) {
                Helpers.SwapEntries(ref assemblyFiles, bootfileIndex, 0);
            }

            string asmOut = getOuputFilename(project, "asm.o");
            compileAssembly(linkable, asmOut, output, assemblyFiles, standardOutput);
            Helpers.AddObject(ref outputFiles, asmOut);

            //if there are no C code/header files, then there is no point
            //compiling and linking them with the ASM code.
            if (!linkable) {
                if (File.Exists(asmOut)) {
                    File.Move(asmOut, finalOutput);
                }
                return output;
            }
        }

        //compile all the C code
        string cOut = getOuputFilename(project, "c.o");
        compileC(cOut, output, cCodeFiles, cHeaderFiles, standardOutput);
        Helpers.AddObject(ref outputFiles, cOut);

        //if there was no success, do not continue with linking.
        if (output.Errors.Length != 0) { return output; }

        //link the c and assembly code together.
        link(
            outputFiles,
            finalOutput,
            output,
            standardOutput);
        return output;
    }
Example #20
0
    private void compileAssembly(bool linkable, string outputFile, StandardCompileOutput<Project> output, fileObj[] files, StandardOutputCallback stdOut)
    {
        if (File.Exists(outputFile)) { File.Delete(outputFile); }

        //collapse all the files into one file to compile
        string collapsed = collapseFiles(files, ".asm");

        //compile
        outputEntry[] errors = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        compileAssembly(linkable, ref errors, ref warnings, collapsed, outputFile, stdOut);
        processCompileResults(files, output, errors, warnings);

        //clean up
        File.Delete(collapsed);
    }
Example #21
0
    private void link(string[] files, string outputFile, StandardCompileOutput <Project> output, StandardOutputCallback stdOut)
    {
        //perform the link
        outputEntry[] errors   = new outputEntry[0];
        outputEntry[] warnings = new outputEntry[0];
        link(ref errors, ref warnings, files, outputFile, stdOut);

        //add the errors and warnings to the output object
        for (int c = 0; c < errors.Length; c++)
        {
            output.addError(null, 0, 0, errors[c].message);
        }
        for (int c = 0; c < warnings.Length; c++)
        {
            output.addWarning(null, 0, 0, warnings[c].message);
        }
    }
Example #22
0
    public void Start(int memory, StandardOutputCallback standardOutput)
    {
        //already running?
        if (Running) { return; }

        #region Invoke Qemu
        string qemuArguments = "-qmp tcp:127.0.0.1:4444,server,nowait " +
                               "-cdrom \"" + new FileInfo(p_DiskImage).FullName + "\" " +
                               "-m " + memory;

        //create a processlink process so that if this process is killed
        //it automatically kills the emulator as well.
        standardOutput("Launching process linker...");
        if (!File.Exists("processlink.exe")) {
            standardOutput("  Error! ProcessLink.exe is not found!");
            return;
        }
        p_Process = new Process() {
            StartInfo = new ProcessStartInfo {
                FileName = "processLink.exe",
                Arguments = "-id " + Process.GetCurrentProcess().Id + " " +
                            "-f \"" + new FileInfo("emulators/qemu/qemu.exe").FullName + "\" " +
                            "-a " + qemuArguments,
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardOutput = true
            }
        };

        //get the qemu process id from the spawn process
        int qemuPID = -1;
        p_Process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) {
            if (e.Data == null || qemuPID != -1) { return; }
            qemuPID = Convert.ToInt32(e.Data);
        };

        //launch the process
        standardOutput("Starting Qemu...");
        p_Process.Start();
        standardOutput("   Process linker PID=" + p_Process.Id);
        p_Process.BeginOutputReadLine();

        //wait until the spawner has launched Qemu
        while (qemuPID == -1) ;
        p_QemuProcess = Process.GetProcessById(qemuPID);
        standardOutput("   Started, PID=" + qemuPID);

        #endregion

        //connect to the Qemu Monitor
        p_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        int connectStart = Environment.TickCount;
        standardOutput("Connecting to Qemu's QMP service...");
        while (Environment.TickCount < connectStart + 1000) {
            try {
                p_Socket.Connect("localhost", 4444);
                p_Stream = new NetworkStream(p_Socket, true);
                break;
            }
            catch { }
        }

        //timed out?
        if (!p_Socket.Connected) {
            standardOutput("Error! Unable to connect to Qemu's QMP service");
            Stop();
            return;
        }

        //get the initial response from the server
        standardOutput("Performing handshake with QMP Server");
        JSONObject handshake = JSONObject.Decode("", monitorRead())[0];
        handshake = (JSONObject)handshake["QMP"];

        //get the version of the qemu emulator
        JSONObject version = (JSONObject)handshake["version"];
        version = (JSONObject)version["qemu"];
        int versionMajor = Convert.ToInt32(version["major"]);
        int versionMinor = Convert.ToInt32(version["minor"]);

        //enter command mode
        monitorWrite("{ \"execute\": \"qmp_capabilities\" }");
        JSONObject result = JSONObject.Decode(monitorRead())[0];
        result = (JSONObject)result["return"];
        if (result.ChildValues[0].ChildCount > 0) {
            standardOutput("Unable to enter into QMP Command mode!");
            Stop();
            return;
        }

        //create an event listener
        standardOutput("Starting event listener...");
        Thread eventListener = new Thread(new ThreadStart(delegate {
            while (Running) {
                //send a blank signal to the server so we don't interfere
                //with current messages.
                Monitor.Enter(p_SyncLock);
                monitorExecute("", null);
                monitorReadObject(false);
                Monitor.Exit(p_SyncLock);

                Thread.Sleep(100);
            }
        }));
        eventListener.Start();
        standardOutput("  Listening...");

        //success
        standardOutput("Qemu Emulator version " + versionMajor + "." + versionMinor);
        standardOutput("Qemu Emulator ready...");

        return;
        EmulationProcessor ps = GetProcessors()[0];
        while (true) {
            int time = Environment.TickCount;
            GetRegisters(ps);
            Console.WriteLine((Environment.TickCount - time) + "ms");
        }

        new DebugRegisters(this).Show();
    }
Example #23
0
    public ICompilerOutput <Project> CompileProject(Project project, StandardOutputCallback standardOutput)
    {
        #region split up every file in the project into a code file

        fileObj[] assemblyFiles = new fileObj[0];
        fileObj[] cCodeFiles    = new fileObj[0];
        fileObj[] cHeaderFiles  = new fileObj[0];

        project.Root.Enumerate(true, delegate(ProjectEntity e) {
            if (!(e is ProjectFile))
            {
                return(true);
            }

            //add the filename into the appropriate code file list
            ProjectFile file = (ProjectFile)e;
            string ext       = file.Extension.ToLower();
            switch (ext)
            {
            case ".c":
                Helpers.AddObject(ref cCodeFiles, new fileObj(file));
                break;

            case ".h":
                Helpers.AddObject(ref cHeaderFiles, new fileObj(file));
                break;

            case ".asm":
                Helpers.AddObject(ref assemblyFiles, new fileObj(file));
                break;
            }
            return(true);
        });
        #endregion

        //define the final output file
        string finalOutput = getOuputFilename(project, "build.bin");
        StandardCompileOutput <Project> output = new StandardCompileOutput <Project>(finalOutput, project);
        string[] outputFiles = new string[0];
        if (File.Exists(finalOutput))
        {
            File.Delete(finalOutput);
        }

        //define whether or not the assembly code should
        //be linked (no point in linking if theres nothing
        //to link with)
        bool linkable = cCodeFiles.Length != 0 || cHeaderFiles.Length != 0;

        //compile the assembly
        if (assemblyFiles.Length != 0)
        {
            //make sure that the main entry point assembly file is at the top
            //of the list to be compiled first.
            int bootfileIndex = -1;
            for (int c = 0; c < assemblyFiles.Length; c++)
            {
                if (assemblyFiles[c].ProjectFile.Name.ToLower() == "boot.asm")
                {
                    bootfileIndex = c;
                    break;
                }
            }
            if (bootfileIndex != -1)
            {
                Helpers.SwapEntries(ref assemblyFiles, bootfileIndex, 0);
            }

            string asmOut = getOuputFilename(project, "asm.o");
            compileAssembly(linkable, asmOut, output, assemblyFiles, standardOutput);
            Helpers.AddObject(ref outputFiles, asmOut);

            //if there are no C code/header files, then there is no point
            //compiling and linking them with the ASM code.
            if (!linkable)
            {
                if (File.Exists(asmOut))
                {
                    File.Move(asmOut, finalOutput);
                }
                return(output);
            }
        }

        //compile all the C code
        string cOut = getOuputFilename(project, "c.o");
        compileC(cOut, output, cCodeFiles, cHeaderFiles, standardOutput);
        Helpers.AddObject(ref outputFiles, cOut);

        //if there was no success, do not continue with linking.
        if (output.Errors.Length != 0)
        {
            return(output);
        }

        //link the c and assembly code together.
        link(
            outputFiles,
            finalOutput,
            output,
            standardOutput);
        return(output);
    }