A Whirlwind Tutorial on Creating Teensy ELF Executables for Linux
muppetlabs.com
muppetlabs.com
- very first, unoptimized program compiles to 15440 bytes (vs 3998 on OP's system);
- super-optimized hand-rolled assembly (tiny.s) compiles to 12780 bytes (vs 368 on OP's system).
On my Rocky Linux 8.5 machine with kernel 4.18.x, gcc 8.5.x, and glibc 2.28.x, the sample C program compiles to 17,800 bytes - after stripping, it's down to 6,768 bytes. 16,292 bytes in 32 bit mode, 6,148 after stripping.
To put things in perspective, the AVR ATTiny85 only has 8KB of program memory, meaning this simple "return 42" program wouldn't even fit as-is.
Seems glibc does add a considerable amount of "bloat" to the binary. I wonder what a properly "golfed" ELF binary file size would be today?
$ gcc -Wall -s -nostdlib tiny.o; wc -c a.out
12780 a.out
$ gcc -Wall -s -nostdlib tiny.o -static
$ wc -c a.out
4304 a.out
Bulk of what remains is page-size alignment. Linux works with 4KB pages: $ getconf PAGESIZE
4096
...so it makes sense that gcc (ld, really) aligns to that. But we can dial it down: $ gcc -Wall -s -nostdlib tiny.o -static \
-Wl,-zmax-page-size=64; wc -c a.out
400 a.out
...and a bit more could be shaven by dropping Build ID: $ strip -R .note.gnu.build-id a.out; wc -c a.out
344 a.out
This wonderful piece of software: https://github.com/aunali1/super-strip seem to find more things to remove, although not sure what would be that: $ sstrip a.out; wc -c a.out
220 a.out
Of course, this is not quite "golfed", and I too, would love to see OP's article updated to x86_64 and current crop of gcc/binutils.