Rather than running Linux binaries with the lxrun front-end, it is possible to turn lxrun into a program interpreter, ld-linux.so.* - the Linux runtime linker. The path of the interpreter is actually embedded in every dynamic linked ELF executable - for standard UnixWare / OpenServer ELF it is /usr/lib/libc.so.1, and for Linux it is /lib/ld-linux.so.1 (or, ld-linux.so.2 for executables linked with GNU libc v2).
The direct execution of Linux binaries in this manner is in the latest development releases of lxrun. At the time of this writing, support for this model of execution is available on UnixWare platforms only. SCO OpenServer places some rather strict limitations on what a program interpreter can be. Overcoming these restrictions is a current development topic.
The following discourse, from Mike Davidson (firstname.lastname@example.org) the author of lxrun, details some of the issues involved in the direct execution model:
"It's actually quite simple to build a version of lxrun which can be used as the initial program interpreter for Linux binaries. There are, however, a couple of problems:
At first I thought that we could avoid this by just porting a version of the Linux runtime linker to run native on UNIX, but this looks like it may be more trouble than it is worth - while the Linux runtime linker is quite well written it has to deal with some rather unpleasant limitations in the GNU tools - in particular it looks as if GNU ld doesn't support the equivalent of our -Bsymbolic option which makes writing the startup code for a runtime linker almost impossible (in fact the Linux runtime linker startup routine is just one massive function that uses nothing but local variables and which does all of it's system calls with chunks of inline assembler)."
Consideration was given to implementing a software interrupt kernel module rather than relying on the "int $0x80" segmentation violation. Rather than sacrifice the elegance and portability of a "non-kernel" Linux emulation strategy, Mike Davidson has suggested that:
This probably isn't really necessary. Assuming that we are really only interested in Linux ELF (and not Linux a.out) we can use the dynamic linker to "preload" the Linux runtime compatibility library in such a way that almost all of the system calls will be intercepted and handled directly by the compatibility library without ever going down to an actual "int $0x80" instruction.
Thus far, performance has not been an issue as very little negative impact has been detected. The main cost of running a Linux application under lxrun is the overhead of catching the segmentation violation (int $0x80), fixing up the structures/errors/returns, and mapping the system call. Since much of what lxrun does is done in the normal course of executing a system call natively, the SIGSEGV intercept is the main overhead.
In order to avoid catching SIGSEGV for every system call, current lxrun development plans on implementing a "pre-load" of the "Linux runtime compatibility library" (see the previous subsection). With the direct execution of Linux ELF binaries described above, it is possible to pre-load this library on startup. That is, the binary has already been identified as a Linux ELF binary since it is attempting to load /lib/ld-linux.so.1. This "fake" program interpreter knows it will have to map system calls so, rather than waiting for the SIGSEGV to trigger the mapping, the program interpreter can "pre-map". Thus, system calls made by the Linux ELF binary under the control of such a program interpreter would not cause general protection traps. In this scenario, nearly all of the performance overhead of running Linux binaries with lxrun is eliminated.