Search code examples
cmacosassembly

Are there any negative side-effects to using -mmacosx-version-min and -segalign flags to reduce padding space in an executable?


I noticed that if I compile a C program with the gcc or clang command on macOS 10.15.7 the executable will be around 50 KB, no matter how simple the program. In older versions, the same program produces an executable of just 8 KB. I also noticed that most of the extra size are just large contiguous regions of 0 bytes.

The answer for what the 0 bytes are and how they can be reduced is explained here: Why is my hello world binary mostly zeroes?

Newer versions have more segments in the executable that have to be aligned and their default alignment is larger. Both of these lead to much more padding space in the executable. I can use -mmacosx-version-min=10.14 and -Wl,-segalign,0x1000 to force the compiler to use a lesser alignment and get rid of the __DATA_CONST section, thus reducing the executable size by up to about 40 KB.


My question is, if using -mmacosx-version-min=10.14 and -Wl,-segalign,0x1000 can both reduce the executable to a fraction of the size for simple programs and can allow the executable to run on older versions of macOS too, are there any unforeseen penalties to using them? If not, why are these settings not the default?

For example:

  • Will the smaller executables without the __DATA_CONST segment and smaller segment alignment somehow incur a (significantly) longer startup overhead?
  • Are there any machines that use the same executable format but would not be able to run them that could otherwise run the larger executables?

For what reason(s), if any, might I not want to indiscriminately/automatically use -mmacosx-version-min=10.14 and/or -Wl,-segalign,0x1000 to optimize all of my executables for size?


Solution

  • Adapted from a comment:

    A segment size of 0x1000 shouldn't make a difference on x86_64, but it's not available on arm64. The kernel will refuse to load your binary. And __DATA_CONST is a security thing, but it arguably has a much greater impact on the arm64e ABI (which Apple has still not stabilized for 3rd parties) than for arm64 without pointer authentication.