When your hft app gets way bigger than 2,147,483,647.

Vladimir Sakharuk 1 min read

Tried building a -no-pie binary with debug symbols and slammed into this gem:

compiler.log
log
gcc/x86_64-conda-linux-gnu/13.4.0/crtbegin.o:(.text+0x7):
relocation R_X86_64_32S out of range: 2197535928 is not in [-2147483648, 2147483647];
references section '.tm_clone_table'

Root cause: gcc’s 32-bit-sized start of constructors meeting a codebase that’s… not 32-bit-sized anymore.

Fix that worked:

Recompile GCC’s crtbegin.o and crtend.o with the large code model:

bash
gcc -mcmodel=large -fno-pic -O2 -c gcc/crtstuff.c -o crtbegin.o
gcc -mcmodel=large -fno-pic -O2 -c gcc/crtstuff.c -DCRT_END -o crtend.o

Overlay the toolchain in the app and dial the app back to medium:

CMakeLists.txt
text
add_compile_options(-mcmodel=medium)
target_compile_options(my_binary PRIVATE -B/home/vladimir/toolchain-ovr)

Yes, I rebuilt parts of GCC. Yes, it actually helped to create 28 GB binary. Compiling toolchains by hand is an… immense kind of fun.

Takeaways

  • Turning off PIE can surface gnarly relocation limits.
  • Know your x86-64 code models: small/medium/large isn’t just trivia.
  • Sometimes the only way out is through the CRT.