Skip to content

[flang] Error-prone representation of large common symbols #149222

@vzakhari

Description

@vzakhari

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    flangFlang issues not falling into any other category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions