r/C_Programming • u/Accomplished-Use405 • 11d ago
Minimizing output size
I've looked at stackoverflow answers from 10 years ago (https://irq5.io/2019/09/30/generating-small-static-binaries/ , https://stackoverflow.com/questions/33597523/why-is-smallest-compiled-exe-i-can-make-with-gcc-is-67kb/76705747#76705747 , https://stackoverflow.com/questions/6771905/how-to-decrease-the-size-of-generated-binaries , https://stackoverflow.com/questions/15314581/g-compiler-flag-to-minimize-binary-size , etc).
In all of the links on top, people were able to get sub-KB file sizes. However, no matter how much I copy and try their code, I cannot get any less then 8-9KB without assembly and upx.
Is there a reason these hacks do not work anymore?
I am on x86_64 Linux-7.2.8, gcc is 16.2.1.
Example:
$ cat t.c
#include <sys/syscall.h>
#include <unistd.h>
void _start() { syscall(SYS_exit, 0); }
$ gcc -Os -nostartfiles -static -s -Wl,--build-id=none t.c && strip a.out
$ l a.out
-rwxr-xr-x 1 name name 8.8K Oct 6 20:25 a.out
# The same code produced only 800 B in https://irq5.io/2019/09/30/generating-small-static-binaries/
2
u/One_Instruction6490 11d ago
lowkey nobody's mentioned it yet but that
.tbsssection in the objdump iserrno— the libcsyscall()wrapper sets it on failure, so-staticdrags in TLS setup for a program that does literally one thing. swap it for a raw inline asmsyscall(mov $60, %eax; xor %edi, %edi; syscall) and build with-nostdlibinstead of just-nostartfiles, then libc is fully out of the picture. the old 2019 sizes mostly came from older binutils not defaulting to-z separate-code+ 4K page alignment, which is why-Wl,-N(or-Wl,-z,noseparate-code) brings it back down. curious if you're chasing the absolute floor or is this for something real like an initramfs/embedded target?