-
Notifications
You must be signed in to change notification settings - Fork 38.7k
build: Fix undefined reference to __mulodi4 #21882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Does this fix work in your cases? |
|
Concept and tested-only ACK 207b4e2 didn't review |
|
This allows to remove the workaround in oss-fuzz: oss-fuzz# git diff
diff --git a/projects/bitcoin-core/build.sh b/projects/bitcoin-core/build.sh
index 66d827f8..b2c4f36e 100755
--- a/projects/bitcoin-core/build.sh
+++ b/projects/bitcoin-core/build.sh
@@ -19,13 +19,6 @@
# This will also force static builds
if [ "$ARCHITECTURE" = "i386" ]; then
export BUILD_TRIPLET="i686-pc-linux-gnu"
- # Temporary workaround for:
- # CXXLD test/fuzz/fuzz
- # test/fuzz/test_fuzz_fuzz-multiplication_overflow.o: In function `void (anonymous namespace)::TestMultiplicationOverflow<long long>(FuzzedDataProvider&)':
- # /src/bitcoin-core/src/test/fuzz/multiplication_overflow.cpp:30: undefined reference to `__mulodi4'
- # clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
- # Makefile:5495: recipe for target 'test/fuzz/fuzz' failed
- sed -i 's|defined(HAVE_BUILTIN_MUL_OVERFLOW)|defined(IGNORE_BUILTIN_MUL_OVERFLOW)|g' "./src/test/fuzz/multiplication_overflow.cpp"
else
export BUILD_TRIPLET="x86_64-pc-linux-gnu"
fi |
I'll have a look and let you know |
|
Does this issue only affect building the fuzz binary? This wasn't clear for me from the OP in #21294. |
Yes, the OP in #21294 points to some other places, but the exact version of the code is still unknown (or I missed it). On the current master the bug is reproducible for fuzz binary only (using Armbian 21.02.3 Focal). |
Makes sense, thanks for letting me know, maybe we can wait a bit for tested confirmation that this solves the referenced issues. |
|
I did test this in #21882 (comment), but I did not review |
|
The steps to reproduce from #21920 (comment) can be used here as well |
fanquake
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be broken out into it's own macro, with an explanation of why it's needed.
Is this actually limited to 32-bit? When compiling with Clang 11, on a 64-bit system, it is easy to recreate the same problem. i.e:
int f(__int128 a, __int128 b, __int128 *p) {
return __builtin_mul_overflow(a, b, p);
}
int main() {}# clang --version
Ubuntu clang version 11.0.0-2~ubuntu20.04.1
Target: x86_64-pc-linux-gnu
# clang test.c
/usr/bin/ld: /tmp/test-de745b.o: in function 'f':
test.c:(.text+0x61): undefined reference to '__muloti4'
# clang test.c --rtlib=compiler-rt
<success>Why isn't this broken for 64-bit builds?
configure.ac
Outdated
| [ | ||
| AC_MSG_RESULT([no]) | ||
| AX_CHECK_LINK_FLAG([--rtlib=compiler-rt -lgcc_s], | ||
| [FUZZ_BINARY_LDFLAGS="--rtlib=compiler-rt -lgcc_s"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is linking against GCCs runtime library actually needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is.
After adding --rtlib=compiler-rt the new linking error appears:
CXXLD bitcoind
CXXLD bitcoin-cli
CXXLD bitcoin-util
CXXLD test/fuzz/fuzz
/usr/bin/ld: test/fuzz/fuzz-addition_overflow.o: undefined reference to symbol '__aeabi_unwind_cpp_pr0@@GCC_3.5'
/usr/bin/ld: /lib/arm-linux-gnueabihf/libgcc_s.so.1: error adding symbols: DSO missing from command line
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:6141: test/fuzz/fuzz] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/home/hebasto/bitcoin/src'
make[1]: *** [Makefile:15996: all-recursive] Error 1
make[1]: Leaving directory '/home/hebasto/bitcoin/src'
make: *** [Makefile:821: all-recursive] Error 1
On master with the following diff
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -251,7 +251,6 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/merkleblock.cpp \
test/fuzz/message.cpp \
test/fuzz/muhash.cpp \
- test/fuzz/multiplication_overflow.cpp \
test/fuzz/net.cpp \
test/fuzz/net_permissions.cpp \
test/fuzz/netaddress.cpp \no error fires.
__aeabi_unwind_cpp_pr0is part of the standard ARM exception handling code...
Do we use
|
|
Updated 207b4e2 -> 70d89ff (pr21882.02 -> pr21882.03):
|
|
Concept ACK |
|
On some level this problem is really strange. You're absolutely not supposed to have to link anything special to be able to use this basic C functionality. Functions with double underscore If this is a workaround for a bug in a specific compiler version, please make this more clear and add a comment so that we know when it can be removed again. |
We are already use double-underscore-named functions:
|
I'm not sure about a specific clang version. From https://bugs.llvm.org/show_bug.cgi?id=28629 I can assume that all supported clang versions are affected. |
Even there it's a compiler builtin / intrinsic. It's supposed to be part of the compiler or its support code, not a library you have to explicitly link. And I see no calls to |
|
Could rebase to simplify testing? |
Done. |
|
tested-only ACK bd55f62 On vanilla Ubuntu Focal: Before: After: Clean |
build-aux/m4/bitcoin_runtime_lib.m4
Outdated
| AC_LANG_PUSH(C++) | ||
| AC_MSG_CHECKING([whether __builtin_mul_overflow can be used without compiler-rt]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AIUI, this test succeeds with non-clang, but __builtin_mul_overflow doesn't actually get checked at all. Maybe the test itself should be conditional on using clang?
|
Perhaps something like this would be better? diff --git a/build-aux/m4/bitcoin_runtime_lib.m4 b/build-aux/m4/bitcoin_runtime_lib.m4
index 6af5514e6b7..9834b6c7965 100644
--- a/build-aux/m4/bitcoin_runtime_lib.m4
+++ b/build-aux/m4/bitcoin_runtime_lib.m4
@@ -5,14 +5,10 @@
# - https://bugs.llvm.org/show_bug.cgi?id=28629
m4_define([_CHECK_RUNTIME_testbody], [[
- #if defined(__clang__) && defined(__has_builtin)
- #if __has_builtin(__builtin_mul_overflow)
bool f(long long x, long long y, long long* p)
{
return __builtin_mul_overflow(x, y, p);
}
- #endif
- #endif
int main() { return 0; }
]])
@@ -21,18 +17,23 @@ AC_DEFUN([CHECK_RUNTIME_LIB], [
AC_LANG_PUSH(C++)
- AC_MSG_CHECKING([whether __builtin_mul_overflow can be used without compiler-rt])
+ AC_MSG_CHECKING([for __builtin_mul_overflow])
AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_RUNTIME_testbody])], [
- AC_MSG_RESULT([yes])
- ], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], [1], [Define if you have a working __builtin_mul_overflow])
+ ], [
+ ax_check_save_flags="$LDFLAGS"
+ LDFLAGS="$LDFLAGS --rtlib=compiler-rt -lgcc_s"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_RUNTIME_testbody])], [
+ AC_MSG_RESULT([with additional linker flags])
+ RUNTIME_LDFLAGS="--rtlib=compiler-rt -lgcc_s"
+ AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], [1], [Define if you have a working __builtin_mul_overflow])
+ ],[
AC_MSG_RESULT([no])
- AX_CHECK_LINK_FLAG([--rtlib=compiler-rt -lgcc_s],
- [RUNTIME_LDFLAGS="--rtlib=compiler-rt -lgcc_s"],
- [AC_MSG_FAILURE([cannot figure out how to use __builtin_mul_overflow])],
- [$LDFLAG_WERROR],
- [AC_LANG_SOURCE([_CHECK_RUNTIME_testbody])])
])
+ LDFLAGS=$ax_check_save_flags
+ ])
AC_LANG_POP
AC_SUBST(RUNTIME_LDFLAGS)
diff --git a/src/test/fuzz/multiplication_overflow.cpp b/src/test/fuzz/multiplication_overflow.cpp
index a4b158c18b5..9f617668569 100644
--- a/src/test/fuzz/multiplication_overflow.cpp
+++ b/src/test/fuzz/multiplication_overflow.cpp
@@ -2,6 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
@@ -10,14 +14,6 @@
#include <string>
#include <vector>
-#if defined(__has_builtin)
-#if __has_builtin(__builtin_mul_overflow)
-#define HAVE_BUILTIN_MUL_OVERFLOW
-#endif
-#elif defined(__GNUC__) && (__GNUC__ >= 5)
-#define HAVE_BUILTIN_MUL_OVERFLOW
-#endif
-
namespace {
template <typename T>
void TestMultiplicationOverflow(FuzzedDataProvider& fuzzed_data_provider)
That way failure to make |
When compiling with clang on 32-bit systems the __mulodi4 symbol is defined in compiler-rt only. Github-Pull: bitcoin#21882 Rebased-From: bd55f62
When compiling with clang on 32-bit systems the __mulodi4 symbol is defined in compiler-rt only.
|
Updated bd55f62 -> e4c8bb6 (pr21882.04 -> pr21882.05, diff): |
luke-jr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK e4c8bb6
|
tested-only ACK e4c8bb6 Could suffix title with "... in fuzz binary"? |
fanquake
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK e4c8bb6 - it's a bit of an awkward workaround to carry, but at-least it's contained to the fuzzers.
e4c8bb6 build: Fix undefined reference to __mulodi4 (Hennadii Stepanov) Pull request description: When compiling with clang on 32-bit systems the `__mulodi4` symbol is defined in compiler-rt only. Fixes bitcoin#21294. See more: - https://bugs.llvm.org/show_bug.cgi?id=16404 - https://bugs.llvm.org/show_bug.cgi?id=28629 ACKs for top commit: MarcoFalke: tested-only ACK e4c8bb6 luke-jr: utACK e4c8bb6 fanquake: ACK e4c8bb6 - it's a bit of an awkward workaround to carry, but at-least it's contained to the fuzzers. Tree-SHA512: 93edb4ed568027702b1b9aba953ad50889b834ef97fde3cb99d1ce70076d9c00aa13f95c86b12d6f59b24fa90108d93742f920e15119901a2848fb337ab859a1
This should no-longer be necessary now that bitcoin/bitcoin#21882 has been merged upstream.
This should no-longer be necessary now that bitcoin/bitcoin#21882 has been merged upstream.
When compiling with clang on 32-bit systems the __mulodi4 symbol is defined in compiler-rt only. Github-Pull: bitcoin#21882 Rebased-From: e4c8bb6
|
This is still an issue with clang, as of ac92ab6:- |
Are you talking about 0.21? If so it's because this PR has not been backported to 0.21. |
|
@hebasto no, the master branch as of 9 days ago. |
backport: merge bitcoin#21404, bitcoin#21415, bitcoin#19314, bitcoin#21882, bitcoin#16939, bitcoin#19084, bitcoin#20602, bitcoin#20253, bitcoin#20480, bitcoin#20736 (remove deprecated logic, use standard library alternatives)
When compiling with clang on 32-bit systems the
__mulodi4symbol is defined in compiler-rt only.Fixes #21294.
See more: