The following patch makes sure we build the 32bit multilib libgcov with large file support on x86_64-linux. libgcov.h ends up using auto-host.h via including tconfig.h which is only valid for the main multilib (and on x86_64 doesn't need explicit large-file support defines). That libgcc ends up using that is probably from times where it wasn't at the toplevel, some files already include auto-target.h generated by libgcc configure but most do so after including tsystem.h which is of course too late. I suppose libgcc files shouldn't include tconfig.h from gcc/, but that's a change going to far for this bug ;)
Thus, this makes libgcov.h include auto-target.h (but in the correct position) plus adds AC_SYS_LARGEFILE to libgccs configure. With that I properly end up with 32bit libgcov.a using fopen64 and open64 as fopen/open seem to fail for some filesystems and inode numbers that do not fit 32bits even if the files in question are not large. Failure mode is: int main(void) { return 0; } niffler:/home/mue/src # gcc -m32 --coverage -o t testit.c niffler:/home/mue/src # ./t profiling:/home/mue/src/testit.gcda:Cannot open Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk and branches after a while? libgcov is the only libgcc module doing I/O. Other than libgcov libgomp, libcilkrts, libmpx and libstdc++ are similarly affected (they use fopen on the 32bit multilib) but not fixed. libubsan, libasan, libssp, libbacktrace and libgfortran use open. While libgfortran configury has AC_SYS_LARGEFILE, the open use leaks in through libbacktrace (ubsan/asan might have the same issue, didn't investigate). libbacktrace lacks AC_SYS_LARGEFILE. Thanks, Richard. 2017-06-14 Richard Biener <rguent...@suse.de> PR gcov-profile/81080 * configure.ac: Add AC_SYS_LARGEFILE. * libgcov.h: Include auto-target.h before tsystem.h to pick up _FILE_OFFSET_BITS which might differ for multilibs. * config.in: Regenerate. * configure: Likewise. Index: libgcc/configure.ac =================================================================== --- libgcc/configure.ac (revision 249145) +++ libgcc/configure.ac (working copy) @@ -191,6 +191,8 @@ GCC_NO_EXECUTABLES AC_PROG_CC AC_PROG_CPP_WERROR +AC_SYS_LARGEFILE + AC_CHECK_SIZEOF([double]) AC_CHECK_SIZEOF([long double]) AS_VAR_ARITH([double_type_size], [$ac_cv_sizeof_double \* 8]) Index: libgcc/libgcov.h =================================================================== --- libgcc/libgcov.h (revision 249145) +++ libgcc/libgcov.h (working copy) @@ -38,6 +38,7 @@ /* This path will be used by libgcov runtime. */ #include "tconfig.h" +#include "auto-target.h" #include "tsystem.h" #include "coretypes.h" #include "tm.h" Index: libgcc/config.in =================================================================== --- libgcc/config.in (revision 249145) +++ libgcc/config.in (working copy) @@ -71,3 +71,9 @@ /* Define to 1 if the target use emutls for thread-local storage. */ #undef USE_EMUTLS + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES Index: libgcc/configure =================================================================== --- libgcc/configure (revision 249145) +++ libgcc/configure (working copy) @@ -672,6 +672,7 @@ enable_version_specific_runtime_libs with_slibdir enable_maintainer_mode with_build_libsubdir +enable_largefile enable_decimal_float with_system_libunwind enable_explicit_exception_frame_registration @@ -1308,6 +1309,7 @@ Optional Features: --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer + --disable-largefile omit support for large files --enable-decimal-float={no,yes,bid,dpd} enable decimal float extension to C. Selecting 'bid' or 'dpd' choses which decimal floating point format @@ -4061,6 +4063,205 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_c_preproc_warn_flag=yes +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi +fi + + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects