binaryfileselfreact-os

Running ELF binaries on ReactOS


Please be patient in answering as I am new to all this and want to get my basics 100 percent right. I am a Mechanical Engineer, so do not be harsh. I am learning about some very basic low level stuff and was interested in understanding a concept related to compiler backends. The C/C++ compiler output is probably the machine code specifically tailored for the computer architecture. This also means that it should be same in Windows and Linux if both run on the same hardware, say, i7 processor. But there is another layer of difference in the form of binary format. That is, we have ELF(Executable and Linkable Format) on Linux and PE/COFF(Portable Executable) on Windows.

Thus, I feel, the compilers on Linux and Windows have backends that work differently and emit binaries in ELF or PE/COFF format.

ReactOS is a clone of Windows and is binary compatible to an extent with Windows.

Is it theoretically possible to have a LOADER in ReactOS that understands ELF and loads it properly?

I understand that we need to have a layer of software that maps the Linux APIs to ReactOS APIs. If such a mapping layer exists, does my question make sense?


Solution

  • Loader is not enough.

    Operating systems have their own system call interface. I don't know too much about Linux and Windows binary APIs, last time I was using system calls directly was MS-DOS.

    In MS-DOS, you can call DOS function by loading function code to AH register, then call INT 21H. Register AL is often used as sub-function or primary parameter. E.g. I can recall how to exit a program:

        MOV AX,4C01H   ; funciton AH = $4C (exit), error code is AH = 1
        INT 21H
    ; program gets never here
    

    So, other operating systems provide other fashion interface. E.g. AmigaDOS has exec.library's address on the absolute address of 4 (yep, $00000004), and library functions can be accessed thru a jump table located to negative offsets to library's "base" address (-4, -8 etc.). Other libraries' pointer can be asked from exec.library, by using open function.

    Okay, MS-DOS and AmigaDOS runs on different architectures, but it's a good example of how operating system calls may differ. Software interrupts vs. library addresses provided by the first library.

    Sometimes, difference is a luck. When the different operating system calls does not interfere, it's possible to write a wrapper, which receives alien operating system calls, and transforms them to host operating system. It would be perfect, if operating systems APIs would differ only the order of parameters of system calls - but the situation is more difficult. Simpler function can be mapped to other OS's flavour, but more complex functions - with callbacks! - are harder. Wrappers may emulate not only functions, but bugs of the operating system.

    Anyway, there are some good stuff in this genre.

    A good example is CygWin, which let you run Linux programs under Win32. When I last used it, there were no problems running any command-line stuff, even with threads, network etc. EDITED: it requires re-compiling and libs as @fortran says.

    For Linux, WINE is a nice effort to run Win32 apps. There are even official Linux versions of commercial software, which use WINE! If your program doesn't utilize the lastest Windows API calls, WINE should work.

    As Linux and BSD are both POSIX compatible operating systems, it's no surprise, that such a thing, like Linux Compatibility Layer for BSD exists.