https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63793
Bug ID: 63793 Summary: -mcmodel=medium in gfortran on x86_64 emits references that are RIP relative (instead of using the GOT) Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: howarth at bromo dot med.uc.edu The src_flexwrf_v3.1 package from http://flexpart.eu/downloads/src_flexwrf_v3.1.tar.gz fails to link on x86_64 darwin when compiled with the required -mcmodel=medium option due to a code generation bug that the darwin linker fails on. The offending file is compiled with... gfortran -c -I/sw/include -fno-common -mcmodel=medium -fconvert=little-endian -finit-local-zero -fno-range-check convmix_kfeta.f90 and the linkage later fails as... gfortran *.o -o flexwrf31_gnu_serial -L/sw/lib -fno-common -mcmodel=medium -fconvert=little-endian -finit-local-zero -fno-range-check -L/sw/lib -lnetcdff final section layout: __TEXT/__text addr=0x1000017F5, size=0x00126A11, fileOffset=0x000017F5, type=1 __TEXT/__stubs addr=0x100128206, size=0x0000023A, fileOffset=0x00128206, type=28 __TEXT/__stub_helper addr=0x100128440, size=0x000003C6, fileOffset=0x00128440, type=32 __TEXT/__cstring addr=0x100128808, size=0x00000B97, fileOffset=0x00128808, type=13 __TEXT/__const addr=0x1001293A0, size=0x0000A6BC, fileOffset=0x001293A0, type=0 __TEXT/__eh_frame addr=0x100133A60, size=0x00004598, fileOffset=0x00133A60, type=19 __DATA/__got addr=0x100138000, size=0x000002B8, fileOffset=0x00138000, type=29 __DATA/__nl_symbol_ptr addr=0x1001382B8, size=0x00000010, fileOffset=0x001382B8, type=29 __DATA/__la_symbol_ptr addr=0x1001382C8, size=0x000002F8, fileOffset=0x001382C8, type=27 __DATA/__data addr=0x1001385C0, size=0x000008F0, fileOffset=0x001385C0, type=0 __DATA/__common addr=0x100138EC0, size=0x000000EC, fileOffset=0x00000000, type=25 __DATA/__bss5 addr=0x100138FC0, size=0x00000070, fileOffset=0x00000000, type=25 __DATA/__pu_bss5 addr=0x100139040, size=0x000017F0, fileOffset=0x00000000, type=25 __DATA/__bss6 addr=0x10013A840, size=0x00855AF4, fileOffset=0x00000000, type=25 __DATA/__pu_bss2 addr=0x100990334, size=0x0000047C, fileOffset=0x00000000, type=25 __DATA/__pu_bss6 addr=0x1009907C0, size=0x01EBCAA8, fileOffset=0x00000000, type=25 __DATA/__pu_bss3 addr=0x10284D268, size=0x00000010, fileOffset=0x00000000, type=25 __DATA/__pu_bss4 addr=0x10284D280, size=0x0000001C, fileOffset=0x00000000, type=25 __DATA/__bss2 addr=0x10284D29C, size=0x00000020, fileOffset=0x00000000, type=25 __DATA/__huge addr=0x10284D2C0, size=0x129E8DD40, fileOffset=0x00000000, type=25 ld: 32-bit RIP relative reference out of range (4246534707 max is +/-4GB): from _convmix_kfeta_ (0x100058E3C) to _sumpartgrid.2471 (0x1FD229580) in '_convmix_kfeta_' from convmix_kfeta.o for architecture x86_64 collect2: error: ld returned 1 exit status The darwin linker developer has provided the following analysis of this bug... ----------------------------------------------------------------------------------- This is a little known aspect of x86_64 mach-o that allows the use of the small code model everywhere (that is not need a large code model). When the compiler references “large” ( >= 1MB) zero-fill data, it should do it through the GOT (instead of direct RIP relative reference). When the linker lays out the output, if it is bigger than 2GB, it moves all large zero-fill symbols to a new __DATA,__huge section which the linker puts last. As long as all the uses of moved large data is through the GOT, this just works and you can have very large mach-o binaries. In this case the file from convmix_kfeta.o defines _sumpartgrid.2471 (which is a 4MB zero-fill symbol) but that same file has a reference to _sumpartgrid.2471 from the function _convmix_kfeta_ that is RIP relative (instead of using the GOT).