Browse Source

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.
Nick Mathewson 8 years ago
parent
commit
6d6c8287d5
3 changed files with 51 additions and 0 deletions
  1. 4 0
      changes/bug19079
  2. 40 0
      configure.ac
  3. 7 0
      src/common/include.am

+ 4 - 0
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.

+ 40 - 0
configure.ac

@@ -801,6 +801,46 @@ fi
 CFLAGS_BUGTRAP="$CFLAGS_FTRAPV $CFLAGS_ASAN $CFLAGS_UBSAN"
 CFLAGS_BUGTRAP="$CFLAGS_FTRAPV $CFLAGS_ASAN $CFLAGS_UBSAN"
 CFLAGS_CONSTTIME="$CFLAGS_FWRAPV"
 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 <stdint.h>
+          #include <stdlib.h>
+	  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 <stdint.h>
+          #include <stdlib.h>
+	  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 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 persuade ourselves that they're suitable for code that needs to be
 dnl constant time.
 dnl constant time.

+ 7 - 0
src/common/include.am

@@ -62,7 +62,14 @@ else
 readpassphrase_source=
 readpassphrase_source=
 endif
 endif
 
 
+if ADD_MULODI4
+mulodi4_source=src/ext/mulodi/mulodi4.c
+else
+mulodi4_source=
+endif
+
 LIBOR_CTIME_A_SRC = \
 LIBOR_CTIME_A_SRC = \
+   $(mulodi4_source) \
    src/ext/csiphash.c   \
    src/ext/csiphash.c   \
    src/common/di_ops.c
    src/common/di_ops.c