From 6d6c8287d5e060117bfa066f87d4e2fc08ab708d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 18 May 2016 09:44:05 -0400 Subject: [PATCH] Include __mulodi4 in libor_ctime when it fixes clang -m32 -ftrapv We use a pretty specific pair of autoconf tests here to make sure that we only add this code when: a) a 64-bit signed multiply fails to link, AND b) the same 64-bit signed multiply DOES link correctly when __mulodi4 is defined. Closes ticket 19079. --- changes/bug19079 | 4 ++++ configure.ac | 40 ++++++++++++++++++++++++++++++++++++++++ src/common/include.am | 7 +++++++ 3 files changed, 51 insertions(+) create mode 100644 changes/bug19079 diff --git a/changes/bug19079 b/changes/bug19079 new file mode 100644 index 0000000000..6cbc6cee3b --- /dev/null +++ b/changes/bug19079 @@ -0,0 +1,4 @@ + o Minor features (build): + - Detect and work around a libclang_rt problem that prevents clang from + finding __mulodi4() on some 32-bit platforms. This clang bug would keep + -ftrapv from linking on those systems. Closes ticket 19079. diff --git a/configure.ac b/configure.ac index de59c752bc..8465b43262 100644 --- a/configure.ac +++ b/configure.ac @@ -801,6 +801,46 @@ fi CFLAGS_BUGTRAP="$CFLAGS_FTRAPV $CFLAGS_ASAN $CFLAGS_UBSAN" CFLAGS_CONSTTIME="$CFLAGS_FWRAPV" +if test "$have_clang" = "yes"; then + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $CFLAGS_FTRAPV" + AC_MSG_CHECKING([whether clang -ftrapv can link a 64-bit int multiply]) + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #include + #include + int main(int argc, char **argv) + { + int64_t x = ((int64_t)atoi(argv[1])) * (int64_t)atoi(argv[2]) + * (int64_t)argv[3]; + return x == 9; + } ]])], + [ftrapv_can_link=yes; AC_MSG_RESULT([yes])], + [ftrapv_can_link=no; AC_MSG_RESULT([no])]) + mulodi_fixes_ftrapv=no + if test "$ftrapv_can_link" = "no"; then + AC_MSG_CHECKING([whether defining __mulodi4 fixes that]) + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #include + #include + int64_t __mulodi4(int64_t a, int64_t b, int *overflow) { + *overflow=0; + return a; + } + int main(int argc, char **argv) + { + int64_t x = ((int64_t)atoi(argv[1])) * (int64_t)atoi(argv[2]) + * (int64_t)argv[3]; + return x == 9; + } ]])], + [mulodi_fixes_ftrapv=yes; AC_MSG_RESULT([yes])], + [mulodi_fixes_ftrapv=no; AC_MSG_RESULT([no])]) + fi + AM_CONDITIONAL(ADD_MULODI4, test "$mulodi_fixes_ftrapv" = "yes") + CFLAGS="$saved_CFLAGS" +fi + dnl These cflags add bunches of branches, and we haven't been able to dnl persuade ourselves that they're suitable for code that needs to be dnl constant time. diff --git a/src/common/include.am b/src/common/include.am index c39ad8d16b..222afe0291 100644 --- a/src/common/include.am +++ b/src/common/include.am @@ -62,7 +62,14 @@ else readpassphrase_source= endif +if ADD_MULODI4 +mulodi4_source=src/ext/mulodi/mulodi4.c +else +mulodi4_source= +endif + LIBOR_CTIME_A_SRC = \ + $(mulodi4_source) \ src/ext/csiphash.c \ src/common/di_ops.c