-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Description
The linker fails for a Fortran program (repro.f90.gz) that is linked with a library:
$ flang -mcmodel=medium repro.f90 -lmylib
/tmp/repro-585cda.o: in function `_QQmain':
FIRModule:(.text+0xb): failed to convert GOTPCREL relocation against 'ccc_'; relink with --no-relax
FIRModule:(.text+0x1f): failed to convert GOTPCREL relocation against 'ccc_'; relink with --no-relax
FIRModule:(.text+0x50): failed to convert GOTPCREL relocation against 'ccc_'; relink with --no-relax
FIRModule:(.text+0x65): failed to convert GOTPCREL relocation against 'ccc_'; relink with --no-relax
I cannot provide the proprietary library, but I am attaching its stats indicating that it does not violate the -mcmodel=medium
limitations: library_stats.txt.gz
ifx
2025 compiler fails the same way:
$ ifx -mcmodel=medium repro.f90 -lmylib
ld: failed to convert GOTPCREL relocation; relink with --no-relax
Gfortran 8.5.0 and 15.1.0 work well.
I believe the problem is that Flang does not mark the large common symbols as SHN_X86_64_LCOMMON
:
$ flang -mcmodel=medium repro.f90 -c
$ readelf -s repro.o
8: 0000000000000008 144 OBJECT GLOBAL DEFAULT COM ccc_
16: 0000000000000008 0x90331e28 OBJECT GLOBAL DEFAULT COM __BLNK__
While gfortran does:
$ gfortran -mcmodel=medium repro.f90 -c
$ readelf -s repro.o
7: 0000000000000020 144 OBJECT GLOBAL DEFAULT COM ccc_
15: 0000000000000020 0x90331e28 OBJECT GLOBAL DEFAULT LARGE_COM __BLNK__
$ llvm-readelf -s repro.o
7: 0000000000000020 144 OBJECT GLOBAL DEFAULT COM ccc_
15: 0000000000000020 2419269160 OBJECT GLOBAL DEFAULT PRC[0xff02] __BLNK__
The large common blocks are allocated in .lbss
by the linker, so they do not affect the distance between the "small" symbols and their relocations: https://lld.llvm.org/ELF/large_sections.html
It looks like LLVM toolchain does not support SHN_X86_64_LCOMMON
at all (see the llvm-readelf
output above that cannot recognize the SHN_X86_64_LCOMMON
flag, which is defined as:
#define SHN_LORESERVE 0xff00
#define SHN_X86_64_LCOMMON (SHN_LORESERVE + 2)