Bug 95194

Summary: bootstrap-lto fails on musl (bundled libintl uses asm aliases)
Product: gcc Reporter: Sergei Trofimovich <slyich>
Component: ltoAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: fw, hubicka, marxin, sam
Priority: P3 Keywords: build
Version: 10.1.0   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200
https://bugs.gentoo.org/show_bug.cgi?id=723370
Host: *-musl Target: *-musl
Build: *-musl Known to work:
Known to fail: Last reconfirmed: 2020-05-19 00:00:00

Description Sergei Trofimovich 2020-05-18 22:37:38 UTC
The bug is originally reported by Andrew Savchenko as https://bugs.gentoo.org/723370. There gcc's bootstrap-lto fails on musl libc. It's slightly different from glibc as libintl relies on glibc-specific gettext symbols like '_nl_msg_cat_cntr'.

The bug:

$ /var/tmp/portage/sys-devel/gcc-10.1.0/work/gcc-10.1.0/configure --host=x86_64-gentoo-linux-musl --build=x86_64-gentoo-linux-musl --prefix=/usr --bindir=/usr/x86_64-gentoo-linux-musl/gcc-bin/10.1.0 --includedir=/usr/lib/gcc/x86_64-gentoo-linux-musl/10.1.0/include --datadir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/10.1.0 --mandir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/10.1.0/man --infodir=/usr/share/gcc-data/x86_64-gentoo-linux-musl/10.1.0/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-gentoo-linux-musl/10.1.0/include/g++-v10 --with-python-dir=/share/gcc-data/x86_64-gentoo-linux-musl/10.1.0/python --enable-languages=c,c++ --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion=Gentoo Hardened 10.1.0 p1 --enable-esp --enable-libstdcxx-time --with-build-config=bootstrap-lto --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-multilib --with-multilib-list=m64 --disable-altivec --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libmudflap --disable-libssp --disable-libada --disable-systemtap --disable-vtable-verify --disable-libvtv --without-zstd --disable-libquadmath --enable-lto --without-isl --disable-libsanitizer --enable-default-pie --enable-default-ssp

$ make -j8 -l10 'LDFLAGS=-march=native -pipe -Wl,-O1,--as-needed,--sort-common,-z,combreloc,-z,relro,-z,now,--relax,--hash-style=gnu' STAGE1_CFLAGS= LIBPATH=/usr/lib/gcc/x86_64-gentoo-linux-musl/10.1.0 'BOOT_CFLAGS=-m64 -march=native -pipe -O2' bootstrap-lean

/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/./prev-gcc/xg++ -B/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/./prev-gcc/ -B/usr/x86_64-gentoo-linux-musl/bin/ -nostdinc++ -B/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/src/.libs -B/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/libsupc++/.libs  -isystem /var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/include/x86_64-gentoo-linux-musl  -isystem /var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/include  -isystem /var/tmp/portage/sys-devel/gcc-10.1.0/work/gcc-10.1.0/libstdc++-v3/libsupc++ -L/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/src/.libs -L/var/tmp/portage/sys-devel/gcc-10.1.0/work/build/prev-x86_64-gentoo-linux-musl/libstdc++-v3/libsupc++/.libs -DEXTRA_OPTIONS     -m64 -march=native -pipe -O2 -fno-checking -flto=jobserver -frandom-seed=1 -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-error=format-diag -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings   -DHAVE_CONFIG_H  -DGENERATOR_FILE -fno-PIE -static-libstdc++ -static-libgcc  -no-pie -o build/genmatch \
    build/genmatch.o ../libcpp/libcpp.a ../libiberty/libiberty.a build/errors.o build/vec.o build/hash-table.o build/sort.o .././libiberty/libiberty.a ./../intl/libintl.a
...
/usr/x86_64-gentoo-linux-musl/bin/ld: /var/tmp/portage/sys-devel/gcc-10.1.0/temp/genmatch.NlicMk.ltrans2.ltrans.o: in function `main':
<artificial>:(.text.startup+0x94ba): undefined reference to `libintl_dgettext'
/usr/x86_64-gentoo-linux-musl/bin/ld: /var/tmp/portage/sys-devel/gcc-10.1.0/temp/genmatch.NlicMk.ltrans3.ltrans.o: in function `cpp_diagnostic(cpp_reader*, cpp_diagnostic_level, cpp_warning_reason, char const*, __va_list_tag (*) [1])':
<artificial>:(.text+0x2732): undefined reference to `libintl_dgettext'
...

Mechanically it fails because 'libintl_dgettext' is decclared as an asm alias:

"""
extern char *dgettext (const char *__domainname, const char *__msgid)
       __asm__ ("" "libintl_dgettext")
       __attribute__ ((__format_arg__ (2)));

$ ../prev-gcc/lto-dump -list errors.o | fgrep dgettext
function  default     0  *libintl_dgettext
$ ../prev-gcc/lto-dump -demangle -list errors.o | fgrep dgettext
function  default     0  dgettext
"""

I'm not sure if gcc should be able to link such a use case for partition=1. Maybe?

Otherwise maybe gcc should default to more portable macro/inline definition of gettext wrappers.

The following workaround helps musl target:

--- a/intl/libgnuintl.h
+++ b/intl/libgnuintl.h
@@ -84,25 +84,25 @@ extern "C" {
    Since Solaris gettext() behaves differently than GNU gettext(), this
    would be unacceptable.

    The redirection happens by default through macros in C, so that &gettext
    is independent of the compilation unit, but through inline functions in
    C++, in order not to interfere with the name mangling of class fields or
    class methods called 'gettext'.  */

 /* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS.
    If he doesn't, we choose the method.  A third possible method is
    _INTL_REDIRECT_ASM, supported only by GCC.  */
 #if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS)
-# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus)
+# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus) && USE_ASM_ALIASES_THAT_BREAK_LTO
 #  define _INTL_REDIRECT_ASM
 # else
 #  ifdef __cplusplus
 #   define _INTL_REDIRECT_INLINE
 #  else
 #   define _INTL_REDIRECT_MACROS
 #  endif
 # endif
 #endif
 /* Auxiliary macros.  */
 #ifdef _INTL_REDIRECT_ASM
 # define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname))
Comment 1 Sergei Trofimovich 2020-05-18 22:38:12 UTC
https://gcc.gnu.org/PR48200 touches on why asm aliases are problematic.