Linking the 4.17.0 amalgamation into an executable fails on x86_64 Linux
with GCC at -O2/-O3 (GCC 13.3, binutils 2.42, Ubuntu 24.04):
sqlite3.c:(.text+0x294eb): relocation truncated to fit: R_X86_64_TPOFF32 against `xoshiro_s'
-O0 links fine. LTO is not required — openSUSE hit the same symbol with LTO
and disabled LTO as a workaround
(https://www.mail-archive.com/commit@lists.opensuse.org/msg143397.html),
but plain -O2 already triggers it.
Reproduce:
./configure && make sqlite3.c
gcc -O2 -c sqlite3.c -DSQLITE_HAS_CODEC -DSQLITE_TEMP_STORE=2 -DSQLITE_THREADSAFE=1 \
-DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown
echo 'extern unsigned long xoshiro_next(void); int main(void){return (int)xoshiro_next();}' > main.c
gcc -O2 main.c sqlite3.o -lcrypto -lpthread -ldl -lm # link fails
Root cause: the thread-local xoshiro state is seeded from its own address
(splitmix64(&xoshiro_s)). GCC constant-folds the seeding and merges the
64-bit golden-ratio constants (k * 0x9e3779b97f4a7c15) into the addend of
the TLS relocation, which cannot be encoded in the signed 32-bit
R_X86_64_TPOFF32 field:
$ readelf -r sqlite3.o | grep xoshiro_s
... R_X86_64_TPOFF32 xoshiro_s + 3c6ef372fe94f82a (= 2 * 0x9e3779b97f4a7c15 mod 2^64)
Workaround: compile the amalgamation with -fPIC -ftls-model=initial-exec
(GOT-based TLS; -ftls-model alone is not enough — without -fPIC GCC
downgrades back to local-exec). A possible upstream fix is laundering the
seed address so the optimizer cannot fold arithmetic into the symbol
reference.
Linking the 4.17.0 amalgamation into an executable fails on x86_64 Linux
with GCC at
-O2/-O3(GCC 13.3, binutils 2.42, Ubuntu 24.04):-O0links fine. LTO is not required — openSUSE hit the same symbol with LTOand disabled LTO as a workaround
(https://www.mail-archive.com/commit@lists.opensuse.org/msg143397.html),
but plain
-O2already triggers it.Reproduce:
Root cause: the thread-local xoshiro state is seeded from its own address
(
splitmix64(&xoshiro_s)). GCC constant-folds the seeding and merges the64-bit golden-ratio constants (
k * 0x9e3779b97f4a7c15) into the addend ofthe TLS relocation, which cannot be encoded in the signed 32-bit
R_X86_64_TPOFF32field:Workaround: compile the amalgamation with
-fPIC -ftls-model=initial-exec(GOT-based TLS;
-ftls-modelalone is not enough — without-fPICGCCdowngrades back to local-exec). A possible upstream fix is laundering the
seed address so the optimizer cannot fold arithmetic into the symbol
reference.