/mips2cs

Convert Mips binaries to equivalent C# code

Primary LanguageC++

INTRODUCTION
============

This is the source code for Mips2cs, a tool for converting MIPS
executables into C# programs.

A full description is on the web site at
http://www.solarflare.org.uk/mips2cs.

For licence conditions see the end of this file.

The remainder of this file contains instructions on how to build and
use Mips2cs. It is assumed that you are using a Linux operating
system.

NOTE: Be advised that this README file was last updated in 2011, so
some of the instructions below might be out of date. (Any pull
requests or suggestions for improvements would be welcome!)


BUILDING THE GCC CROSS COMPILER
===============================

Before we can use Mips2cs we need to be able to create MIPS
executables. To do this we will build GCC as a cross compiler.

You'll need to download the following files:

* Binutils:
  ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/binutils/releases/binutils-n.n.n.tar.bz2
  (replace n.n.n with the latest version number)

* Newlib: can download from
  ftp://sources.redhat.com/pub/newlib/index.html

* GCC:
  ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-n.n.n/gcc-*-n.n.n.tar.bz2
  (get gcc-core and gcc-g++)

You'll also need to install some dependencies: MPFR, MPC, GMP and
libz. (On Debian you can install the following packages: libgmp3-dev,
libmpfr-dev, libmpc-dev, libz-dev.)

Then you can build the cross compiler as follows:

$ export PREFIX=/usr/local/cross-tools  # Set this to where you want the tools to be installed
$ export TARGET=mips-elf
$ export PATH=$PATH:$PREFIX/bin         # will probably want to add this to .bashrc

$ tar xjf binutils-n.n.n.tar.bz2
$ mkdir build-binutils
$ cd build-binutils
$ ../binutils-n.n.n/configure --prefix=$PREFIX --target=$TARGET --with-sysroot=$PREFIX/$TARGET
$ make
$ make install    # may need to run this as root
$ cd ..

$ tar xzf newlib-n.n.n.tar.gz
$ mv newlib-n.n.n gcc-n.n.n
$ tar xjf gcc-core-n.n.n.tar.bz2
$ tar xjf gcc-g++-n.n.n.tar.bz2
$ mv gcc-n.n.n gcc-plus-newlib

$ mkdir build-gcc
$ cd build-gcc
$ ../gcc-plus-newlib/configure --prefix=$PREFIX
                               --target=$TARGET
                               --with-local-prefix=$PREFIX/$TARGET
                               --with-sysroot=$PREFIX/$TARGET
                               --enable-languages=c,c++
                               --enable-multilib
                               --disable-libssp
                               --disable-zlib
                               --enable-sjlj-exceptions
                               --with-newlib
$ make
$ make install     # may need to run this as root
$ cd ..

After this process is complete you will have mips-elf versions of the
GCC tools (mips-elf-gcc, mips-elf-ld, etc). These behave just like the
normal versions, except they produce MIPS executables instead of
native ones.


BUILDING MIPS2CS
================

Mips2cs itself is written in Haskell. You will need to install the GHC
Haskell compiler. You will also need to install the "bytestring" and
"elf" libraries (the command "cabal install bytestring elf" should do
it).

Then you can go into the "src" subdirectory and type the following:

  ghc --make -O Main.hs

This will create the mips2cs executable in the current directory. (The
file name will be "Main".)

TODO: A future version of Mips2cs should use the Cabal build system to
simplify the build process.


RUNTIME LIBRARIES
=================

Mips2cs comes with two "runtime libraries" which act as an interface
between the MIPS executable and the generated C# code. Each library
consists of some C code (which must be linked in when building the
MIPS executable) and some C# code (which must be included when
building the final C# program).

The two libraries are:

1) Console_lib. This contains just enough to get stdin and stdout to
work. This is suitable for building simple console-only programs (e.g.
"hello world" programs).

2) "Coercri". This provides everything that console_lib does, but also
includes a C++ class framework for displaying 2D graphics and reading
mouse input. This is suitable for building simple 2D games/demos and
is used in the demo game (see below).

For convenience a script is provided to automatically build the
console_lib. To run this, go into the console_lib/src directory and
execute build.sh. This will create "console_lib.a" which is a MIPS
static library file.

Currently there is no automatic script for building the Coercri
library.

If the provided libraries are insufficient for your needs then you can
use the Mips2cs "callback" mechanism to define your own C# functions
that can be called from C/C++. Currently there is no documentation for
this; but you could try looking at the source code for the libraries
provided, and in particular the "MipsCallbacks" interface.


RUNNING THE MIPS2CS TEST HARNESS
================================

Mips2cs has an automatic test harness which tests the complete Mips2cs
process, from building the MIPS code using GCC, translating it to C#
using Mips2cs, building an executable using Mono, and checking that
the final executable runs correctly.

To run the test harness go into the "tests" directory and type
"./runtests.hs". The tests will run for a few minutes. If all is well
you will see an "All tests passed" message.

Note: Before you can run the tests you will need to have built Mips2cs
and built the console_lib library (see instructions above).


HOW TO USE MIPS2CS
==================

This section assumes you have a C or C++ program called my_program.c
(or my_program.cpp) and you want to use Mips2cs to convert this into
C# code. It also assumes you are using the console_lib library (see
above).

The first step is to compile your C program to a MIPS executable. You
can use a command like the following:

  mips-elf-gcc my_program.c  \
     -Wl,--start-group /path/to/console_lib.a -lc -Wl,--end-group  \
     -o my_program.mips  \
     -Wl,--emit-relocs  \
     -msoft-float  \
     -O2

This compiles "my_program.c" into the executable "my_program.mips".
Note the "-Wl,--emit-relocs" option which tells the compiler to output
relocation information in the executable (Mips2cs requires this so
that it can compute jump addresses correctly). Note also
"-msoft-float" which tells GCC to use software FPU emulation (Mips2cs
does not currently support the hardware FPU instructions). "-O2"
specifies the required optimization level; you can adjust this if you
like.

For C++ use the following instead:

  mips-elf-g++ my_program.cpp  \
     -Wl,--start-group -lstdc++ -lc /path/to/console_lib.a -Wl,--end-group  \
     -o my_program.mips  \
     -Wl,--emit-relocs  \
     -msoft-float  \
     -O2

(The only differences are the use of g++ instead of gcc, and the
addition of -lstdc++, which gives you the standard C++ library
including STL support.)


Once we have my_program.mips, we can use Mips2cs to convert it to a C#
program, as follows:

  src/Main my_program.mips my_program.cs -O2

This will create my_program.cs. The "-O2" option tells Mips2cs to
optimize the generated C# code. Generally this is recommended because
it will produce shorter and more efficient C# code. However, if
mips2cs takes too long to run, you can reduce it to "-O1" or even turn
off optimization completely.


Finally we can use a C# compiler to compile my_program.cs to a .NET
executable. You will need to compile ConsoleLibMain.cs and
ConsoleLibCallbacks.cs (from the console_lib/cs directory) together
with my_program.cs. If you're using Visual Studio, simply include
these three files in a project and compile. If you're using Mono, a
command like the following should work:

  gmcs my_program.cs ConsoleLibMain.cs ConsoleLibCallbacks.cs -out:my_program.exe

You can then just run my_program.exe, and it should behave exactly the
same as if you had compiled the program to native code!


USING THE "COERCRI" GRAPHICAL LIBRARY / BUILDING THE DEMO GAME
==============================================================

The Coercri library allows some simple use of XNA from the C++ side.
It consists of a C++ class library providing simple 2D graphics and
mouse input functionality, together with C# code which implements that
interface by making calls to XNA.

A demo game, "bouncy_ball_game.cpp" is included which illustrates how
to use Coercri. To build the demo, go into the bouncy_ball_game
directory and run either of the following scripts:

 * sdl_build.sh. This builds a native code version of the game. You
   will need to have the SDL development libraries installed.

 * xna_build.sh. This uses GCC to convert the game to MIPS machine
   code (file "xna.mips") and then uses Mips2cs to create a C# program
   (file "xna.cs"). You can add xna.cs to a Visual Studio project,
   together with all the *.cs files from the coercri/xna/cs/ folder,
   and build a Windows/XNA version of the game. (In theory you could
   also build an Xbox 360 version; however, you would need to modify
   the code to use a 360 controller instead of a mouse!)

Note: Coercri depends on Boost so you may have to edit the scripts to
point to where you have the Boost libraries installed.

The source code for Coercri is available so you can use it as a basis
for your own games if you wish. In theory, you can call any XNA
function from the C++ code. You will need to write appropriate
"MipsCallbacks" functions in C#, and then provide a suitable C or C++
interface on top of those callbacks. The Coercri code provides
examples of how to do this.

TODO: A future version of Mips2cs should provide a more convenient way
of calling C# code from C++. Ideally, a script should be provided that
imports a C# class definition and exports a set of header and source
code files allowing that class to be easily called from C++.


COPYRIGHT INFO
==============

Mips2cs is Copyright (C) Stephen Thompson, 2011. 

Mips2cs is distributed under the Boost Software Licence, Version
1.0. The text of the licence is as follows.

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.


CONTACT DETAILS
===============

Stephen Thompson
Email: stephen@solarflare.org.uk
Website: http://www.solarflare.org.uk/

16th August 2011