Page 2 of 2

Re: My ELFs are so big

Posted: Mon Jan 22, 2024 8:31 am
by eekee
AndrewAPrice wrote:GUI programs link with Skia which adds a dependency on libxml2, harfbuzz, freetype, libjpeg.
I woke up this morning recalling a 9front discussion in which a leading dev concluded that you need dynamic linking for GUI. (This was years ago now, opinions may have changed.) Some time after that discussion, a GUI server came to light. The concept was simple: The program (or even shell script) starts the GUI server, sending and receiving messages over the server's stdio. This certainly shrinks program binares. It's enough to save some memory on a statically-linked system; the text section of the GUI server is shared between all instances. Further savings could be made if the server were a single instance; font caching comes to mind.

Re: My ELFs are so big

Posted: Wed Jan 24, 2024 9:13 am
by AndrewAPrice
thewrongchristian wrote: Interesting. What made the difference in the end? Was it just recompiling with clang? Or did you end up stripping the resulting binaries?
I switched to Clang and got linked time optimization working.
the wrongchristian wrote: Fair enough, but it's unlikely all of that 8MB is actually mapped in. You only need to map in the code that is executed (assuming demand paging), so if the bulk of the files was debug symbols that got removed, then you'll have saved little in the way of memory usage.
My ELF loading code doesn't do demand paging and copies any segment where p_type == PT_LOAD and p_filesz >= 0.

Re: My ELFs are so big

Posted: Mon Aug 26, 2024 7:00 am
by thewrongchristian
AndrewAPrice wrote: Wed Jan 24, 2024 9:13 am
thewrongchristian wrote: Interesting. What made the difference in the end? Was it just recompiling with clang? Or did you end up stripping the resulting binaries?
I switched to Clang and got linked time optimization working.
the wrongchristian wrote: Fair enough, but it's unlikely all of that 8MB is actually mapped in. You only need to map in the code that is executed (assuming demand paging), so if the bulk of the files was debug symbols that got removed, then you'll have saved little in the way of memory usage.
My ELF loading code doesn't do demand paging and copies any segment where p_type == PT_LOAD and p_filesz >= 0.
I recently discovered the GCC -ffunction-sections and linker --gc-sections options (in a bzt Makefile) that might help anyone else struggling with large binaries.

Basically, it looks like this puts each function in its own section (instead of putting everything in .text section), allowing the linker to remove unused sections and thus unused functions. Looks like it's aimed at static binary use case, so I might give it a whirl (not that I have problems with big binaries, demand loading helps there.)

https://gcc.gnu.org/onlinedocs/gcc/Opti ... n-sections

Re: My ELFs are so big

Posted: Mon Aug 26, 2024 7:37 am
by nullplan
There is also -fdata-sections, which additionally puts all data objects into their own sections. Apparently, use of these options also prevents some GCC/binutils bugs (where it erroneously generates a local call when an external one would have been called for).

But there's a limit to how much this can trim. If you call printf(), you still get all the floating-point code, even if you don't use it. And the OP here used quite heavyweight C++ libraries.

Re: My ELFs are so big

Posted: Tue Aug 27, 2024 8:41 am
by sh42
I noticed on some newer GCC build that I needed to add the (from the wiki) options to output in elf64-little format to get the binary size down to the minimum. this was kernel mode though, but I did not need to do it on older versions. I believe this was GCC 13 or 14 which made me do this. I did not see that on your switches, so perhaps that's the difference between the clang/llvm and the GCC setup? I am really not sure _why_ this was happening, and found it a bit illogical, but I just 'tried all the things' and ended up with that in my build flags to reduce binary size to a minimum.