26

Brace yourselves, this question will likely appear naive and/or foolish, seeing as I am relatively new to the inner workings of unix like systems, and programming in general.

Ready? Ok! I will go through about 3 levels of ludicrosity, increasing as I go along.


We have two systems with similar hardware (main point being the processor, let us say a standard intel core 2 duo).

One is running (insert your linux distro here: Ubuntu will be used henceforth), and the other is running let's say Mac OS X.

One compiles an equivalent program, Let us say something like:

int main()
{
    int cat = 33;
    int dog = 5*cat;
    return dog;
}

The code is extremely simple, because I don't want to consider the implications of shared libraries yet.

When compiled on the respective systems. Is not the main difference between the output a matter of ELF vs Mach-O? If one were to strip each binary of the formatting, leaving a flat binary, wouldn't the disassembled machine instructions be the same? (with perhaps a few differences depending on the compilers habits/tendencies).

1.) If one were to develop a program to repackage the flat binary produced from our Ubuntu system, in the Mach-O formatting, would it run in the Mac OS X system? Then, if one only had the compiled binary of the supposed program above, and one had this mystical tool for repackaging flat binaries, would simple programs be able to run on the Mac OS X system?


Now let us take it a bit further.

We now have a program with source such as:

#include <stdio.h>
int main()
{
    printf("I like tortoises, but not porpoises");
    return 0;
}

2.)Assuming this program is compiled and statically linked, would our magical program still be able to repackage the raw binary in the Mach-O format and have it work on mac os X? Seeing as it would not need to rely on any other binaries, (for which the mac system would not have in this case)


And now for the final level;

3.)What if we used this supposed program to convert all of the necessary shared libraries to the Mach-O format, and then instead compiled the program above with dynamic linking. Would the program still succeed to run?

That should be it for now, obviously each step of absurdity relies on the previous base, to even make sense. so If the very first pillar gets destroyed, I doubt there would be much merit to the remaining tiers.

I definitely would not even go as far as to think of this with programs with GUI's in mind. Windowing systems would likely be a whole other headache. I am only considering command line programs at this stage.

Now, I invite the world to correct me,and tell me everything that is wrong with my absurd line of thinking.

24

You forget one crucial thing, namely that your program will have to interact with the operating system to do anything interesting.

The conventions are different between Linux and OS X so the same binary cannot run as-is without essentially having a chunk of operating system dependent code to be able to interact with it. Many of these things are hidden away in libraries, which you then need to link in, and that means your program needs to be linkable, and linking is also different between the two systems.

And so it goes on and on. What on the surface sounds like doing the same thing is very different in the actual details.

  • 4
    This is basically correct as to what the problem is, but the issue isn't really libraries (which could be dragged along) but system calls, which are requests to the OS kernel. If the OS doesn't provide a compatible system call interface, you are out of luck. – mattdm Feb 22 '11 at 22:11
  • Aah, This is excellent. This is exactly the kind of constructive correction I was hoping for. Thanks a bunch :D Could you tell me more about these supposed system calls, or redirect me to somewhere I can learn more about them? – zec Feb 22 '11 at 22:16
  • 2
    They're not "supposed", they are actual. :) Here's a good start: ibm.com/developerworks/linux/library/l-system-calls – mattdm Feb 22 '11 at 22:55
  • 6
    That said, your "crazy" idea isn't completely impossible. Just a lot of work. The Wine project is essentially this for running MS Windows binaries on Linux (or OS X). It provides a translation layer for system calls. wiki.winehq.org/… – mattdm Feb 23 '11 at 0:12
  • Well, I figured it wouldn't be completely impossible, but I also did not expect it to be nearly as simple as I described it. I wrote the question with the intention of being corrected. This at times seems like a more efficient method of getting to the heart of the matter than asking a direct question such as "How do I convert a linux binary to run on Mac OS ". Also I have used wine from time to time, but I had never really pondered about how it worked before, I think I shall go look into it sometime now. – zec Feb 23 '11 at 2:51
15

This is doable if someone wants to spend enough time to make it happen. The Darling project is attempting this, though as of this writing, it's in a pretty primitive state.

It's been done successfully before on other platforms:

  • Solaris and UnixWare include a helper program called lxrun which works something like sudo: you pass your executable name and parameters to the helper and it fixes things up dynamically so that the executable can talk to the OS. The official site (down, archive link) says it's bitrotted.

  • Linux's kernel once had a feature called iBCS that did the reverse, except that it didn't need a helper because the kernel recognized the "foreign" binaries directly. It fell into disrepair during the kernel 2.3 development series, most likely because the small Unix server battle was essentially over once 2.4 came out.

  • FreeBSD's kernel can be configured to recognize Linux binaries and run them as if they were native. This feature appears to be in better shape than the above two.

    OpenBSD and NetBSD have similar features.

OS X has a lot of FreeBSD in it, so porting its Linux support might be straightforward.

  • 1
    One of the reasons this isn't a big deal for Linux programs → other platforms is: there's no significant Linux-only apps for which source isn't available. You want to run your program on OS X or Solaris, recompile it, and there ya go. There may be a little porting to do where the code was written in Linux-specific ways, but generally that's not a lot of work, especially compared to maintaining the compatibility layer. FreeBSD's Linux compatibility was a big deal back when Netscape was a binary distributed for Linux only, and probably still is used for Adobe Flash Player. – mattdm Feb 24 '11 at 0:44
  • @Jörg W Mittag — also, you needed to have the system libraries from the other platform available. This may have been the basis for their suit against AutoZone. But honestly I forget the details and barely care anymore. :) – mattdm Feb 24 '11 at 0:47
  • So what you say is essentially, that if operating system X provides the same services as operating system Y, then a binary can run under both. This is true, but require a deliberate effort for system X. I am unaware of any operating system being compatible in this way with OS X. – Thorbjørn Ravn Andersen Feb 20 '12 at 9:11
  • bitrotten? I'll show myself out. – GnP Dec 13 '14 at 22:22
2

I pretty much agree with everyone, but I want to add that, while this would take a significant amount of time and effort, it wouldn't be nearly as much as it has taken to develop Wine.

Much of the difficultly in Wine development is that they are porting a binary format from a closed source operating system and MANY of the system calls are undocumented. They had to essentially reverse engineer the operating system.

If someone were to do this from one open OS to another open OS, they could likely get it done in 1/10 of the time, since the compatibility layer could quite conceivably be copy/pasted from the other OS if an equivalent native system call doesn't exist. Of course, in most cases across the POSIX world, there will be a native call available.

Another project of note is ReactOS, where they're essentially creating a full binary-compatible version of Windows... no need for Wine.

0

There are a number of specialized Linux apps for which this would be a great help. On the FPGA side, Quartus and Vivado are good examples of programs that run under Linux and there is unlikely to be source code available for them or similar programs that target the latest FPGAs.

I think the simple answer to your question is: recompile on MacOS where you have the source and form a group to provide the capability if you have the time--and it will be a time consuming task.

0

It is technically doable in macOS but not without significant effort, although some of the effort is already done for us.

  • Both macOS and a rebranded Red Hat Enterprise Linux have been certified UNIX 03. This means in principle POSIX calls should have the same API.
  • Both macOS and Linux uses System V ABI for amd64 platform. This means that for amd64 macOS and Linux should have compatible ABI and API.
  • macOS uses Mach-O as its native executable format while Linux uses ELF. This does make things easier, as the executable file format can be used to distinguish whether the compatibility layer should be called. This would require something like binfmt_misc though.
  • There exists a third party macOS kernel extension that provides exactly that. Now we have a way to load convince macOS to load ELF, we need our special ld-linux.so which itself is a Mach-O executable that would load our ELF and run it.

Now what we need is at least a special ld-linux.so that can do the following:

  • Be a Mach-O executable or dyld itself,
  • Can load Linux ELF files into memory at the correct address,
  • Hopefully has the ability to map Linux soname to macOS ones (example /lib/libc.so.6 to /lib/libSystem.B.dylib) and load corresponding Mach-O when a matching ELF is not found, so we can reuse macOS libraries

With just that loader above ELF that does not make direct syscalls has a good chance of working, but ELF with syscalls might not work. A second component that might be useful would be a kernel extension that catches those Linux syscalls and maps them to macOS ones. As of desktop uses, special mesa implementation is needed to map Linux graphics calls to OpenGL.framework and Metal.framework.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.