On Wed, 14 Jun 2017, Richard Biener wrote: > > 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.
Ping. Richard. > 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 > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)