Arm64 binaries too large?

The arm64 binaries are ~10x larger than the x86_64 binaries at Release v1.0.0 · brandonchinn178/xreferee · GitHub.

From AI, I tried adding --enable-split-sections and

  ghc-options: -optl-s
  if os(linux)
    ghc-options: -optl-Wl,-gc-sections
  if os(osx)
    ghc-options: -optl-Wl,-dead_strip

But it didn’t help.

AI says:

Diagnosis: The Linker Garbage Collection (LGC) Is Still Failing Silently

Your x86_64 binary is 2.1 MB because LGC is working. Your ARM64 binary is 18 MB because LGC is not working on that specific target toolchain, even though you are passing the correct flags.

This is a known, intermittent issue in the GHC ecosystem, especially on newer, non-x86 architectures (like ARM64) and certain linker versions (like ld.gold on Linux). The LGC process requires three things to work:

  1. Split Sections: Must be enabled (--enable-split-sections).
  2. LGC Flag: Must be passed to the linker (--gc-sections or -dead_strip).
  3. Toolchain Compatibility: The GHC-generated object files and the target linker must be compatible.

Since you are on GHC 9.12 and the flags are correct, the problem is almost certainly a toolchain incompatibility or a subtle bug preventing GHC from correctly generating object files that the ARM linker can analyze for dead code.

How do I solve this?

2 Likes

it’s a ghc issue, if you do a git blame on .gitlab/generate-ci/gen_ci.hs · master · Glasgow Haskell Compiler / GHC · GitLab on the lines containing splitSectionsBroken you’ll see almost all aarch64 bindists were added that disables split sections in the first place.

it could have been necessary to workaround some aarch64 toolchain issues a few years ago, i don’t remember the exact issue number or if there’s any. but now it’s a good time to revisit those and try to run some ci jobs to see if it’s possible to produce aarch64 release bindists that re-enable split sections. i’ll do it.

update 1: the debian builds are failing with relocation truncated to fit: R_AARCH64_JUMP26 against symbol, so it seems we need to apply -finter-module-far-jumps to the aarch64 builds by default. i’ll make a patch and do a second try.

update 2: i’m even more confused; -finter-module-far-jumps doesn’t solve the linker error on aarch64 debian, but alpine works fine without the flag. in the meantime i might have also found out the culprit of why split sections is broken on windows, testing a fix atm

update 3: i figured out the root cause of why split sections is broken on windows, see Windows: stripped executable sizes, post GHC 8.10.7 (#26494) · Issues · Glasgow Haskell Compiler / GHC · GitLab. unfortunately this requires refactorings in our ncg backend to fix it and i’m out of steam for now, will revisit in the future

update 4: -finter-module-far-jumps is not needed, it works on aarch64 debian if i specify lld as linker (the default is ld.bfd). so it does look like an issue with old linkers. most of the testsuite pass except test-late-plugin. i’ll put up a patch later to remove +no_split_sections for aarch64 linux release builds.

14 Likes