Supporting four operating systems in a 400 byte ELF executable
justine.lol
justine.lol
(I dug into that a little bit, inspired by a previous article here: https://news.ycombinator.com/item?id=31456401 )
Four operating systems is under 400 bytes is pretty good!
I have a 26-byte Hello World that works in DOS 1.x, 2.x, 3.x, 4.x, 5.x, 6.x, Windows 1.x, 2.x, 3.x, 95, 98, 98se, Me, 2k, XP, Vista, 7, 8, 10. If I used CALL 5 I might get down into CP/M-land but possibly miss some of the newer OSs ;-)
I had a weird and pointless project somewhat recently where I wanted to bootstrap a programming environment using only the stock tools on NT 4. I didn't actually finish, but what I did write was pretty contrived. I wrote some code for JScript, which had to run in IE since there was no scripthost, and it would parse some horrible language using a very inefficient IE3 JScript compatible implementation of parser combinators and generate x86 code... And output it in base64 into a textarea. Which I would then need to somehow get back into proper binary data...
So my approach was to write a small DOS compatible COM binary with a really simple base64 decode routine. I'd do this with the DEBUG command, and save it to disk. Then, I'd use redirection in command prompt to feed it base64 and redirect the output to a file.
I was pretty ecstatic to see this awful hack job working somewhat end-to-end.
(I don't have the code, I think it got wiped out when the drive in the laptop I was doing this whole game on died. But it was quite straightforward to implement base64 in very little code; I believe what I wound up doing was accumulating 3 bytes of output from 4 bytes of input with a few conditionals to shift base64 symbols into the corresponding bits and then just some shifting and ORing. No LUTs necessary.)
The latter is used by http://tom7.org/abc
Of course it was Tom7. Of. Course.
Tom7 is a treasure.
x)y'!B:)),DM!G@))p,T]l%)),@@@Hello, world!$XP5]A%=!P[PZ^V!wV!wX5.<(GV(gX534,!(GWr!
it could have been a few bytes shorter, but on 486 you need a jump to flush the prefetch queue
80 C3 xx xx
The first instruction will be harmless on both processors, and even have the same mnemonic: it decodes as either "ADD BX,xxxx" or "ADD B"!
I mean, if one of the non-FreeBSD OSes started insisting on a certain value for e_ident[EI_OSABI] then presumably he'd have to redo all this from scratch with a different technique.
Reminds me of when slack was sold for 30 billion dollars, and Boston Dynamics sold for 1.5 billion. Feels like the market rewards the wrong things sometimes.
If you can't see the value in what Boston Dynamics has created, I have a ToDo list application to sell you for several billion dollars.
On top of that, 3 of the OSs (FreeBSD, NetBSD, OpenBSD) share a common source code ancestry, meaning that the oldest and most fundamental Unix system calls (like `write(2)`) had an excellent chance of remaining compatible.
Yes, calling write(2) on Linux is different, but only in the syscall number. That's also not a coincidence, as the behaviour of write() is highly constrained by POSIX which Linux and the BSDs both adhere to, and the way to pass parameters to the call is specified by the `syscall` instruction.
That there are enough differences in the environment to be able to figure out which of Linux or *BSD the program is running on is a bit of luck, but probably not that much.
For instance, on the OS ABI field in ELF headers:
> Fortunately we can get around this by just setting it to the FreeBSD ABI. This is because FreeBSD is the only UNIX operating system that checks this field.
Or on loading a zero-byte segment into memory:
> However if the size in memory is zero too, then OpenBSD will refuse to run the progarm, whereas the other kernels just don't care.
Someone working on the various operating systems could change those behaviors without knowing that they're breaking this thing. And they wouldn't necessarily be in the wrong to do so. Because it's not really an ABI.
The modern OS space is dominated by 3 big OSes, and a bunch of smaller relatives, that are basically siblings. They share a huge amount of ancestry.
Whereas there are many, many others that are vastly unlike them in almost every way.
What you see as coincidence reflects the fact that these OSes are closely related.
The 3 big OSes now are Windows NT, macOS and Linux. The close relatives I mentioned are the BSDs, and then relative to them very slightly further away, Minix 3, QNX, and then things like GNU HURD, (Open)Solaris, other Unixes, etc.
All implemented mainly in C, all descendants of or inspired by one of just 2 OSes for just 2 DEC minicomputers.
Unix and all Unixes from a DEC PDP-7 OS, that became a lot more like modern Unix when ported to the PDP-11.
All Windows this century is Windows NT. The other forms (Win9x, WinCE etc.) are dead.
All NT is related to VMS, a DEC VAX OS, where the VAX is a 32-bit PDP-11.
They are all siblings.
Some OSes with the same conceptual model (disks, partitions, files, binaries, users, etc.) that are totally different:
* RISC OS.
* Classic MacOS
* AmigaOS (and MorphOS, AROS etc.)
None of these have replaceable "shells". None use file extensions. None have any trace of 8.3 filenames.
Others, like the large family that sprung from CP/M, including Concurrent CP/M, Atari TOS/GEM, etc. are broadly similar because they also came from DEC PDP OSes, but different ones, and were not originally implemented in C or anything because their shared rootstock is contemporaneous with the invention of C.
There are many many OSes that are almost nothing like even this basic model of "disks" with "filesystems" and "source code" that is compiled to "binaries" that are CPU-native and governed by "configuration files" that are probably "plain text".
Symbolics Genera and OpenGenera. IBM OS/400, now called IBM i. Taos and its successors Intent and Elate. Novell Netware, in some ways. Arguably, Inferno, the last of the Unix line.
You're looking at a cluster of closely-related OSes for a single CPU platform and saying hey, one binary can work on all of them, what a coincidence.
In fact, this very clever and ingenious hack is _because they are close relatives_.
You are pointing at a dog, a cat, a lizard, a cow, and a frog and saying "hey, look, what a coincidence: they all have 4 legs and 2 eyes and 1 mouth!"
No, it's because they are all relatives. They're all tetrapods.
But there are also insects and spiders and crustaceans and worms and comb jellies and starfish. All basically unrelated except they're all animals.
(I was going to include jellyfish, but looked at this way, jellyfish and corals and sea anemones are all related: they're all coelenterates.)
I mean, it's OK if the only animals you're familiar with are 4-legged vertebrates, but you should at least be aware that there is, literally and exactly, more to life. I mean, you've seen flies and cockroaches and things, haven't you?