On x86_64, I'm not able to link a ~2GiBytes object file into an executable or a shared library. Using: - binutils-2.31.1-29.fc30.x86_64 - gcc-9.1.1-1.fc30.x86_64 - glibc-devel-2.29-12.fc30.x86_64 Start by assembling the following code: $ cat large.S .section .rodata .globl large .p2align 0 .type large, @object .size large, SIZE large: .zero SIZE $ gcc -DSIZE=$((2**31)) -c -o large.o large.S Then linking the large object as a shared object fails: $ gcc -shared -o liblarge.so large.o /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crti.o: in function `_init': (.init+0xb): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `__gmon_start__' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `deregister_tm_clones': crtstuff.c:(.text+0x3): relocation truncated to fit: R_X86_64_PC32 against `.tm_clone_table' /usr/bin/ld: crtstuff.c:(.text+0xa): relocation truncated to fit: R_X86_64_PC32 against symbol `__TMC_END__' defined in .got.plt section in liblarge.so /usr/bin/ld: crtstuff.c:(.text+0x16): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `_ITM_deregisterTMCloneTable' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `register_tm_clones': crtstuff.c:(.text+0x33): relocation truncated to fit: R_X86_64_PC32 against `.tm_clone_table' /usr/bin/ld: crtstuff.c:(.text+0x3a): relocation truncated to fit: R_X86_64_PC32 against symbol `__TMC_END__' defined in .got.plt section in liblarge.so /usr/bin/ld: crtstuff.c:(.text+0x57): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `_ITM_registerTMCloneTable' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `__do_global_dtors_aux': crtstuff.c:(.text+0x76): relocation truncated to fit: R_X86_64_PC32 against `.bss' /usr/bin/ld: crtstuff.c:(.text+0x81): relocation truncated to fit: R_X86_64_GOTPCREL against symbol `__cxa_finalize@@GLIBC_2.2.5' defined in .text section in //lib64/libc.so.6 /usr/bin/ld: crtstuff.c:(.text+0x8e): relocation truncated to fit: R_X86_64_PC32 against symbol `__dso_handle' defined in .data.rel.ro.local section in /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o /usr/bin/ld: crtstuff.c:(.text+0x9e): additional relocation overflows omitted from the output liblarge.so: PC-relative offset overflow in PLT entry for `__cxa_finalize@@GLIBC_2.2.5' collect2: error: ld returned 1 exit status Or linking the large object as an executable fails: $ cat main.c int main(void) { return 0; } $ gcc -c -o main.o main.c $ gcc -o large main.o large.o /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o: in function `_start': (.text+0x2a): relocation truncated to fit: R_X86_64_GOTPCRELX against symbol `__libc_start_main@@GLIBC_2.2.5' defined in .text section in //lib64/libc.so.6 /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o:(.eh_frame+0x20): relocation truncated to fit: R_X86_64_PC32 against `.text' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o:(.eh_frame+0x50): relocation truncated to fit: R_X86_64_PC32 against `.text' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crti.o: in function `_init': (.init+0xb): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `__gmon_start__' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbegin.o: in function `deregister_tm_clones': crtstuff.c:(.text+0x7): relocation truncated to fit: R_X86_64_32S against `.tm_clone_table' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbegin.o: in function `register_tm_clones': crtstuff.c:(.text+0x38): relocation truncated to fit: R_X86_64_32S against `.tm_clone_table' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbegin.o: in function `__do_global_dtors_aux': crtstuff.c:(.text+0x76): relocation truncated to fit: R_X86_64_PC32 against `.bss' /usr/bin/ld: crtstuff.c:(.text+0x88): relocation truncated to fit: R_X86_64_PC32 against `.bss' /usr/bin/ld: main.o:(.eh_frame+0x20): relocation truncated to fit: R_X86_64_PC32 against `.text' /usr/bin/ld: //usr/lib64/libc_nonshared.a(elf-init.oS): in function `__libc_csu_init': (.text+0x9): relocation truncated to fit: R_X86_64_PC32 against symbol `__init_array_start' defined in .init_array section in large /usr/bin/ld: (.text+0x20): additional relocation overflows omitted from the output collect2: error: ld returned 1 exit status Or linking the large object as an position independent executable (PIE) fails: $ gcc -fPIE -c -o main.o main.c $ gcc -pie -fPIE -o large main.o large.o /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/Scrt1.o: in function `_start': (.text+0x2a): relocation truncated to fit: R_X86_64_GOTPCRELX against symbol `__libc_start_main@@GLIBC_2.2.5' defined in .text section in //lib64/libc.so.6 /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/Scrt1.o:(.eh_frame+0x20): relocation truncated to fit: R_X86_64_PC32 against `.text' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crti.o: in function `_init': (.init+0xb): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `__gmon_start__' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `deregister_tm_clones': crtstuff.c:(.text+0x3): relocation truncated to fit: R_X86_64_PC32 against `.tm_clone_table' /usr/bin/ld: crtstuff.c:(.text+0xa): relocation truncated to fit: R_X86_64_PC32 against symbol `__TMC_END__' defined in .data section in large /usr/bin/ld: crtstuff.c:(.text+0x16): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `_ITM_deregisterTMCloneTable' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `register_tm_clones': crtstuff.c:(.text+0x33): relocation truncated to fit: R_X86_64_PC32 against `.tm_clone_table' /usr/bin/ld: crtstuff.c:(.text+0x3a): relocation truncated to fit: R_X86_64_PC32 against symbol `__TMC_END__' defined in .data section in large /usr/bin/ld: crtstuff.c:(.text+0x57): relocation truncated to fit: R_X86_64_REX_GOTPCRELX against undefined symbol `_ITM_registerTMCloneTable' /usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/crtbeginS.o: in function `__do_global_dtors_aux': crtstuff.c:(.text+0x76): relocation truncated to fit: R_X86_64_PC32 against `.bss' /usr/bin/ld: crtstuff.c:(.text+0x81): additional relocation overflows omitted from the output large: PC-relative offset overflow in PLT entry for `__cxa_finalize@@GLIBC_2.2.5' collect2: error: ld returned 1 exit status Perhaps Glibc and GCC runtimes should probably be generated in a way allowing large relocation (Note: SIZE define can be smaller than 2GiBytes. In particular is has to be anything larger than 2147474944 to trigger the error when building a shared library)
(In reply to Yann Droneaud from comment #0) > Perhaps Glibc and GCC runtimes should probably be generated in a way > allowing large relocation I'm thinking about -mcmodel=large Generate code for the large model. This model makes no assumptions about addresses and sizes of sections. https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/x86-Options.html#index-mcmodel_003dlarge-3 But the option description for ARMv8 AArch64 scares me a bit: -mcmodel=large Generate code for the large code model. This makes no assumptions about addresses and sizes of sections. Programs can be statically linked only. https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/AArch64-Options.html#index-mcmodel_003dlarge
The x86-64 instruction encoding only offers 32-bit PC-relative addressing. This is far more than your typical RISC architecture, but it is still a limit that can be reached on today's machines. -mcmodel=large works around this, at a performance cost, which is why this option is not enabled by default. I do not think there is a bug here; this is working as designed. (The AArch64 architecture is very different and has different limitations.)
I'm marking this CLOSED/NOTABUG. There are limits to the size of objects you can link. We would need a strong rationale to support such objects by default by making it possible for the entire runtime to support such large objects.