llvm-project
llvm-project copied to clipboard
[Sparc] Stage2 fails on Linux CI with "error: cannot apply asm label to function after its first use"
| Bugzilla Link | 48650 |
| Version | trunk |
| OS | Linux |
| Depends On | llvm/llvm-project#48906 |
| Attachments | Preprocessed source for sanitizer_platform_limits_posix.cpp |
| CC | @DimitryAndric,@jrtc27,@rorth |
Extended Description
The stage2 build fails on clang-sparc64-linux-multistage with:
FAILED: projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.sparc.dir/sanitizer_stackdepot.cpp.o /var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/stage1.install/bin/clang++ -DHAVE_RPC_XDR_H=1 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iprojects/compiler-rt/lib/sanitizer_common -I/var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common -Iinclude -I/var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/llvm/include -I/var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common/.. -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -std=c++14 -Wno-unused-parameter -O3 -m32 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -O3 -gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -nostdinc++ -fno-rtti -Wframe-larger-than=570 -Wglobal-constructors -DSANITIZER_SUPPORTS_WEAK_HOOKS=0 -UNDEBUG -std=c++14 -MD -MT projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.sparc.dir/sanitizer_stackdepot.cpp.o -MF projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.sparc.dir/sanitizer_stackdepot.cpp.o.d -o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonSymbolizerNoHooks.sparc.dir/sanitizer_stackdepot.cpp.o -c /var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp In file included from /var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp:17: In file included from /var/lib/buildbot/workers/debian-stadler-sparc64/clang-sparc64-linux-multistage/llvm/compiler-rt/lib/sanitizer_common/sanitizer_stackdepotbase.h:16: In file included from /usr/include/stdio.h:870: /usr/include/bits/stdio-ldbl.h:26:20: error: cannot apply asm label to function after its first use __LDBL_REDIR_DECL (vfprintf)
/usr/include/sys/cdefs.h:467:26: note: expanded from macro '__LDBL_REDIR_DECL'
extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
See: http://lab.llvm.org:8014/#/builders/113/builds/37
The issue has existed for a while but I never actually reported it.
mentioned in issue llvm/llvm-project#48906
This fixes it provided that #49562 is fixed:
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 1edab43e7c0d..0ff9930e2616 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -189,8 +189,12 @@ macro(test_targets) elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") test_target_arch(s390x "" "") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "sparc")
-
test_target_arch(sparc "" "-m32") -
test_target_arch(sparcv9 "" "-m64")
-
if (CMAKE_SIZEOF_VOID_P EQUAL 4) -
test_target_arch(sparc "" "-mcpu=v9" "-m32") -
append("-latomic" CMAKE_LD_FLAGS) -
else() -
test_target_arch(sparcv9 "" "-m64") -
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el") # Gcc doesn't accept -m32/-m64 so we do the next best thing and use # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to matchendif()
OK, it seems that clang handles the combination of "-m32" and "-mcpu=v9" incorrectly:
glaubitz@gcc202:~/llvm-project/build$ clang++ -DHAVE_RPC_XDR_H=1 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iprojects/compiler-rt/lib/sanitizer_common -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common -Iinclude -I/home/glaubitz/llvm-project/llvm/include -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/.. -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Werror=return-type -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -std=c++14 -Wno-unused-parameter -O3 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -O3 -gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -nostdinc++ -fno-rtti -Wframe-larger-than=570 -Wglobal-constructors -UNDEBUG -std=c++14 -MD -MT projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o -MF projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o.d -o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o -c /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp -mcpu=v9 -m32 /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:1890:35: error: no member named 'gregs' in 'mcontext_t' uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; ~~~~~~~~~~~~~~~~~~~~~ ^ /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2101:31: error: no member named 'gregs' in 'mcontext_t' *pc = ucontext->uc_mcontext.gregs[REG_PC]; ~~~~~~~~~~~~~~~~~~~~~ ^ /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2102:31: error: no member named 'gregs' in 'mcontext_t' *sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS; ~~~~~~~~~~~~~~~~~~~~~ ^ 3 errors generated. glaubitz@gcc202:~/llvm-project/build$ g++ -DHAVE_RPC_XDR_H=1 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iprojects/compiler-rt/lib/sanitizer_common -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common -Iinclude -I/home/glaubitz/llvm-project/llvm/include -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/.. -fPIC -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Werror=return-type -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -std=c++14 -Wno-unused-parameter -O3 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fvisibility=hidden -fno-lto -O3 -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -nostdinc++ -fno-rtti -Wframe-larger-than=570 -UNDEBUG -std=c++14 -MD -MT projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o -MF projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o.d -o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommon.sparc.dir/sanitizer_linux.cpp.o -c /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp -mcpu=v9 -m32glaubitz@gcc202:~/llvm-project/build$
Hmm, there are more issues with the sanitizer on Linux/sparc64. I also had to properly define pc and sp on Linux:
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 1edab43e7c0d..94ed0b5e1d19 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -189,7 +189,7 @@ macro(test_targets) elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") test_target_arch(s390x "" "") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "sparc")
-
test_target_arch(sparc "" "-m32")
-
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el") # Gcc doesn't accept -m32/-m64 so we do the next best thing and use diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 25c0751c9a38..c9bf318bfccb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -1883,6 +1883,12 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). #if SANITIZER_SOLARIS uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; +#elif SANITIZER_LINUX +#if defined (arch64)test_target_arch(sparc "" "-mcpu=v9" "-m32") test_target_arch(sparcv9 "" "-m64") - uptr pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; +#else
- uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; +#endif #else // Historical BSDism here. struct sigcontext *scontext = (struct sigcontext *)context; @@ -2086,6 +2092,15 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { ucontext_t *ucontext = (ucontext_t *)context; *pc = ucontext->uc_mcontext.gregs[REG_PC]; *sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS; +# elif SANITIZER_LINUX
- ucontext_t ucontext = (ucontext_t)context; +# if defined (arch64)
- *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
- *sp = ucontext->uc_mcontext.mc_gregs[MC_O6] + STACK_BIAS; +# else
- *pc = ucontext->uc_mcontext.gregs[REG_PC];
- *sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS; +# endif #else // Historical BSDism here. struct sigcontext *scontext = (struct sigcontext *)context; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 35a690cba5c8..0cafa3be234d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -240,7 +240,7 @@ namespace __sanitizer { // Use pre-computed size of struct ustat to avoid <sys/ustat.h> which // has been removed from glibc 2.28. #if defined(aarch64) || defined(s390x) || defined(__mips64) || \
- defined(powerpc64) || defined(arch64) || defined(__sparcv9) || \
- defined(powerpc64) || (defined(arch64) && defined(sparc)) ||
defined(x86_64) || SANITIZER_RISCV64 #define SIZEOF_STRUCT_USTAT 32 #elif defined(arm) || defined(i386) || defined(mips) \
And there are more issues:
FAILED: projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.sparc.dir/sanitizer_linux.cpp.o
/home/glaubitz/llvm-project/stage1.install/bin/clang++ -DHAVE_RPC_XDR_H=1 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iprojects/compiler-rt/lib/sanitizer_common -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common -Iinclude -I/home/glaubitz/llvm-project/llvm/include -I/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/.. -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Werror=return-type -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -std=c++14 -Wno-unused-parameter -O3 -mcpu=v9 -m32 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -O3 -gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -nostdinc++ -fno-rtti -Wframe-larger-than=570 -Wglobal-constructors -DSANITIZER_SUPPORTS_WEAK_HOOKS=0 -UNDEBUG -std=c++14 -MD -MT projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.sparc.dir/sanitizer_linux.cpp.o -MF projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.sparc.dir/sanitizer_linux.cpp.o.d -o projects/compiler-rt/lib/sanitizer_common/CMakeFiles/RTSanitizerCommonNoHooks.sparc.dir/sanitizer_linux.cpp.o -c /home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:1890:35: error: no member named 'gregs' in 'mcontext_t'
uptr pc = ucontext->uc_mcontext.gregs[REG_PC];
~~~~~~~~~~~~~~~~~~~~~ ^
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2101:31: error: no member named 'gregs' in 'mcontext_t'
*pc = ucontext->uc_mcontext.gregs[REG_PC];
~~~~~~~~~~~~~~~~~~~~~ ^
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2102:31: error: no member named 'gregs' in 'mcontext_t'
*sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS;
~~~~~~~~~~~~~~~~~~~~~ ^
3 errors generated.
(...)
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h:1438:3: note: expanded from macro 'CHECK_SIZE_AND_OFFSET'
COMPILER_CHECK(sizeof(((_sanitizer##CLASS *)NULL)->MEMBER) ==
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h:332:30: note: expanded from macro 'COMPILER_CHECK'
#define COMPILER_CHECK(pred) static_assert(pred, "")
^ ~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp:1061:1: error: static_assert failed due to requirement 'sizeof (((__sanitizer::__sanitizer_dirent64 *)__null)->d_off) == sizeof (((dirent64 *)__null)->d_off)' ""
CHECK_SIZE_AND_OFFSET(dirent64, d_off);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h:1438:3: note: expanded from macro 'CHECK_SIZE_AND_OFFSET'
COMPILER_CHECK(sizeof(((_sanitizer##CLASS *)NULL)->MEMBER) ==
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h:332:30: note: expanded from macro 'COMPILER_CHECK'
#define COMPILER_CHECK(pred) static_assert(pred, "")
^ ~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp:1061:1: error: static_assert failed due to requirement '__builtin_offsetof(__sanitizer::__sanitizer_dirent64, d_off) == __builtin_offsetof(dirent64, d_off)' ""
CHECK_SIZE_AND_OFFSET(dirent64, d_off);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/glaubitz/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h:1440:3: note: expanded from macro 'CHECK_SIZE_AND_OFFSET'
COMPILER_CHECK(offsetof(_sanitizer##CLASS, MEMBER) == \
It seems like clang automatically defaults mcpu=v9 to 64 bits.
This is a known issue: cf. Bug 42535. On Solaris/SPARC, only SPARC V9 CPUs are supported and I avoid the issue by relying on that: https://reviews.llvm.org/D86621. No idea about the Linux/sparc situation, though.
This fixes the problem for me:
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 1edab43e7c0d..94ed0b5e1d19 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -189,7 +189,7 @@ macro(test_targets) elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") test_target_arch(s390x "" "") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "sparc")
-
test_target_arch(sparc "" "-m32")
-
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el") # Gcc doesn't accept -m32/-m64 so we do the next best thing and usetest_target_arch(sparc "" "-mcpu=v9" "-m32") test_target_arch(sparcv9 "" "-m64")
@jrtc27: Would you be fine with this change?
This fixes the issue for me although I'm now running into another (unrelated) problem which seems to be a result of a missing libatomic in LDFLAGS:
[9/4273] Linking CXX shared library lib/clang/13.0.0/lib/linux/libclang_rt.ubsan_minimal-sparc.so FAILED: lib/clang/13.0.0/lib/linux/libclang_rt.ubsan_minimal-sparc.so [...] /usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.sparc.dir/ ubsan_minimal_handlers.cpp.o: in function
report_this_error(void*)': /home/glaubitz/llvm-project/compiler-rt/lib/ubsan_minimal/../ sanitizer_common/sanitizer_atomic_clang.h:80: undefined reference to__atomic_compare_exchange_4' clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
This is a known issue: cf. Bug 42535. On Solaris/SPARC, only SPARC V9 CPUs are supported and I avoid the issue by relying on that: https://reviews.llvm.org/D86621. No idea about the Linux/sparc situation, though.
It seems to me a solution could be to move the #include <bits/stdio-ldbl.h> up a bit, so instead of:
/* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ #ifdef __USE_EXTERN_INLINES
include <bits/stdio.h>
#endif #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
include <bits/stdio2.h>
#endif #ifdef __LDBL_COMPAT
include <bits/stdio-ldbl.h>
#endif
you would get:
/* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ #ifdef __LDBL_COMPAT
include <bits/stdio-ldbl.h>
#endif #ifdef __USE_EXTERN_INLINES
include <bits/stdio.h>
#endif #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
include <bits/stdio2.h>
#endif
This fixes the issue for me although I'm now running into another (unrelated) problem which seems to be a result of a missing libatomic in LDFLAGS:
[9/4273] Linking CXX shared library lib/clang/13.0.0/lib/linux/libclang_rt.ubsan_minimal-sparc.so
FAILED: lib/clang/13.0.0/lib/linux/libclang_rt.ubsan_minimal-sparc.so
: && /home/glaubitz/llvm-project/build/./bin/clang++ -fPIC -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Werror=return-type -fdiagnostics-color -Wall -std=c++14 -Wno-unused-parameter -g -Wl,-z,defs -Wl,-z,nodelete -m32 -nodefaultlibs -Wl,-z,text -nostdlib++ -Wl,-rpath-link,/home/glaubitz/llvm-project/build/tools/clang/stage2-bins/./lib -shared -Wl,-soname,libclang_rt.ubsan_minimal-sparc.so -o lib/clang/13.0.0/lib/linux/libclang_rt.ubsan_minimal-sparc.so projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.sparc.dir/ubsan_minimal_handlers.cpp.o -Wl,-rpath,"$ORIGIN/../lib" -lgcc_s -lc && :
/usr/bin/ld: projects/compiler-rt/lib/ubsan_minimal/CMakeFiles/RTUbsan_minimal.sparc.dir/ubsan_minimal_handlers.cpp.o: in function report_this_error(void*)': /home/glaubitz/llvm-project/compiler-rt/lib/ubsan_minimal/../sanitizer_common/sanitizer_atomic_clang.h:80: undefined reference to __atomic_compare_exchange_4'
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
Reported as a bug in glibc: https://sourceware.org/bugzilla/show_bug.cgi?id=27558
Hmm, that sounds more like a bug in glibc then. Although I don't understand the connection between long double math and the __asm label.
Ah, sys/cdefs.h has this part dealing with it:
#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
define __LDBL_COMPAT 1
ifdef __REDIRECT
define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
define __LDBL_REDIR(name, proto) \
__LDBL_REDIR1 (name, proto, _nldbl##name)
define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
define __LDBL_REDIR_NTH(name, proto) \
__LDBL_REDIR1_NTH (name, proto, _nldbl##name)
define __LDBL_REDIR1_DECL(name, alias) \
extern __typeof (name) name __asm (__ASMNAME (#alias));
define __LDBL_REDIR_DECL(name) \
extern __typeof (name) name __asm (__ASMNAME ("_nldbl" #name));
define __REDIRECT_LDBL(name, proto, alias) \
__LDBL_REDIR1 (name, proto, _nldbl##alias)
define __REDIRECT_NTH_LDBL(name, proto, alias) \
__LDBL_REDIR1_NTH (name, proto, _nldbl##alias)
endif
#endif #if !defined __LDBL_COMPAT || !defined __REDIRECT
define __LDBL_REDIR1(name, proto, alias) name proto
define __LDBL_REDIR(name, proto) name proto
define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
define __LDBL_REDIR_NTH(name, proto) name proto __THROW
define __LDBL_REDIR_DECL(name)
ifdef __REDIRECT
define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
define __REDIRECT_NTH_LDBL(name, proto, alias) \
__REDIRECT_NTH (name, proto, alias)
endif
#endif
I.e, if long double math is optional (I guess this might be glibc compile time option, but I'm unsure), and the platform/arch does not support long double, it defines a bunch of redirection macros. These macros appear to want to alias "foo" to "__nldbl_foo", so any calls to long double functions would end up at stubs that know how to handle them. (I'm unsure whether that will just abort at runtime, or pretend that double is the same as long double.)
Otherwise (if the arch does support long double) these redirection macros are no-ops, and effectively empty.
bits/stdio-ldbl.h then has a __LDBL_REDIR_DECL (vfprintf) line, which uses the above macro, together with a bunch of other stdio functions.
It seems to me a solution could be to move the #include <bits/stdio-ldbl.h> up a bit, so instead of:
/* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ #ifdef __USE_EXTERN_INLINES
include <bits/stdio.h>
#endif #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
include <bits/stdio2.h>
#endif #ifdef __LDBL_COMPAT
include <bits/stdio-ldbl.h>
#endif
you would get:
/* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ #ifdef __LDBL_COMPAT
include <bits/stdio-ldbl.h>
#endif #ifdef __USE_EXTERN_INLINES
include <bits/stdio.h>
#endif #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
include <bits/stdio2.h>
#endif
Hmm, that sounds more like a bug in glibc then. Although I don't understand the connection between long double math and the __asm label.
Ah yes, the preprocessed output has:
5288 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, 5289 __gnuc_va_list __arg); ... (this is just the declaration, no 'use' yet 5626 # 1 "/usr/include/bits/stdio.h" 1 3 4 5627 # 38 "/usr/include/bits/stdio.h" 3 4 5628 extern __inline attribute ((gnu_inline)) int 5629 vprintf (const char *__restrict __fmt, __gnuc_va_list __arg) 5630 { 5631 return vfprintf (stdout, __fmt, __arg); 5632 } ... so there is the first 'use' 5735 # 1 "/usr/include/bits/stdio-ldbl.h" 1 3 4 5736 # 23 "/usr/include/bits/stdio-ldbl.h" 3 4 5737 extern __typeof (fprintf) fprintf __asm ("" "_nldbl" "fprintf"); 5738 extern __typeof (printf) printf __asm ("" "_nldbl" "printf"); 5739 extern __typeof (sprintf) sprintf __asm ("" "_nldbl" "sprintf"); 5740 extern __typeof (vfprintf) vfprintf __asm ("" "_nldbl" "vfprintf"); ... and here is the part it is complaining about.
The initial declaration is in stdio.h itself, the inline definition of vprintf (which 'uses' vfprintf) in bits/stdio.h, and the asm stuff is in bits/stdio-ldbl.h.
But note, the __asm label thing is done via a __LDBL_REDIR_DECL macro from sys/cdefs.h, and this is only applied in case of:
#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
I think this is the reason you only see it on sparc64, as that doesn't have long double math, at least according to the glibc sources:
sysdeps/unix/sysv/linux/sparc/sparc32/bits/long-double.h 21:#if !defined __NO_LONG_DOUBLE_MATH && __WORDSIZE == 32 24:# define __NO_LONG_DOUBLE_MATH 1
sysdeps/unix/sysv/linux/sparc/sparc64/bits/long-double.h 21:#if !defined __NO_LONG_DOUBLE_MATH && __WORDSIZE == 32 24:# define __NO_LONG_DOUBLE_MATH 1
What happens with Clang 14.0.0 or newer in use?
It would be nice to have some feedback from Linux/Sparc with Clang 15.
The CI results can be found here: https://lab.llvm.org/staging/#/builders/113
The instance was missing the crypt.h header which is why I installed the libcrypt-dev package.
Multistage builds are fine as long as the compiler-rt build is limited to the native architecture which is what we are doing in Debian:
https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/snapshot/debian/rules#L204
ifneq (,$(filter $(DEB_HOST_ARCH),sparc64))
STAGE_ALL_CMAKE_EXTRA += -DLLVM_HOST_TRIPLE=sparc64-linux-gnu
STAGE_ALL_CMAKE_EXTRA += -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
STAGE_ALL_CMAKE_EXTRA += -DLLVM_PARALLEL_LINK_JOBS=4
endif
However, I don't know how to configure this for the CI. FWIW, the mips64el buildbot has a similar problem (but not the same) with the 32-bit compiler-rt build failing on the 64-bit host.
There is also work being done in glibc to alleviate the issue:
https://sourceware.org/bugzilla/show_bug.cgi?id=27558 https://github.com/zatrazz/glibc/tree/azanella/redir-refactor
@zatrazz
It would be nice to have some feedback from Linux/Sparc with Clang 15.
I believe all but one (or two) issues with Debian/sparc64 are now resolved on main. They could be backported to the release/15.x branch if desired:
- clang: link libatomic for 32-bit Linux/sparc
- same for compiler-rt
- perhaps clang: default to
-mcpu=v9for 32-bit Linux/sparc if this can be resolved in time
One outstanding issue is the __asm issue that started this bug. For now, I've just hacked around this by having clang always predefine __NO_INLINE__ on Linux/sparc. I haven't submitted the patch yet because it's no more than a bad hack, but some resolution is necessary to have compiler-rt build at all.
One outstanding issue is the
__asmissue that started this bug. For now, I've just hacked around this by havingclangalways predefine__NO_INLINE__on Linux/sparc. I haven't submitted the patch yet because it's no more than a bad hack, but some resolution is necessary to havecompiler-rtbuild at all.
This might be resolved automatically once the glibc header changes by @zatrazz are merged into glibc upstream.
It would be nice to have some feedback from Linux/Sparc with Clang 15.
I believe all but one (or two) issues with Debian/sparc64 are now resolved on
main. They could be backported to therelease/15.xbranch if desired:
- clang: link libatomic for 32-bit Linux/sparc
- same for compiler-rt
- perhaps clang: default to
-mcpu=v9for 32-bit Linux/sparc if this can be resolved in timeOne outstanding issue is the
__asmissue that started this bug. For now, I've just hacked around this by havingclangalways predefine__NO_INLINE__on Linux/sparc. I haven't submitted the patch yet because it's no more than a bad hack, but some resolution is necessary to havecompiler-rtbuild at all.
I submitted them before even seeing this comment. Thanks.
It would be nice to have some feedback from Linux/Sparc with Clang 15.
I submitted them before even seeing this comment. Thanks.
Great, thanks. FWIW I've posted a sparc64-unknown-linux-gnu tarball of llvm-15.0.0-rc1 today, with the first two patches and the __NO_INLINE__ hack applied locally, including all but openmp and lldb (no sparc support in either).
One outstanding issue is the
__asmissue that started this bug. For now, I've just hacked around this by havingclangalways predefine__NO_INLINE__on Linux/sparc. I haven't submitted the patch yet because it's no more than a bad hack, but some resolution is necessary to havecompiler-rtbuild at all.This might be resolved automatically once the glibc header changes by @zatrazz are merged into glibc upstream.
True, but how long will this take first to get into upstream glibc and then into Debian packages? While I could even patch the system header on my local T5220 LDom, that's not an option on systems I don't own (like gcc202 in the cfarm).
It would be nice to have some feedback from Linux/Sparc with Clang 15.
I submitted them before even seeing this comment. Thanks.
Great, thanks. FWIW I've posted a
sparc64-unknown-linux-gnutarball of llvm-15.0.0-rc1 today, with the first two patches and the__NO_INLINE__hack applied locally, including all butopenmpandlldb(no sparc support in either).
I saw that, that is a good step forward. Hopefully the issue with glibc can be fixed soon enough.
@zatrazz
True, but how long will this take first to get into upstream
glibcand then into Debian packages?
I could actually build a patched glibc package just for the sparc64 port, once I know that the patches by @zatrazz fix the issue.
My main problem is that so far I was unable to successfully build clang against a patched version of glibc.
While I could even patch the system header on my local T5220 LDom, that's not an option on systems I don't own (like
gcc202in the cfarm).
I have full control over gcc202 and the LLVM CI machine, so I could install a patched package them.
I submitted them before even seeing this comment. Thanks.
and they have all been merged in.
/cherry-pick 1e56821bac02a5d3c6249bbf3ef43b8b569d2551
/branch llvm/llvm-project-release-prs/issue47994
/pull-request llvm/llvm-project-release-prs#150
If I'm not mistaken the root issue was fixed in glibc and that 1e56821bac02a5d3c6249bbf3ef43b8b569d2551 should now be reverted.
Looking at the 2.34 branch I see these backports..
https://github.com/bminor/glibc/commit/2a44960cbc78713c6a2721683a4319d50e71a01f https://github.com/bminor/glibc/commit/b41c535f46e7e7bbd8ff2ac68b94c2348e2f66e4
@rorth