aboutsummaryrefslogtreecommitdiff
path: root/configure.ac
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--configure.ac61
1 files changed, 44 insertions, 17 deletions
diff --git a/configure.ac b/configure.ac
index 1fe61016..cdd72a9f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -869,15 +869,37 @@ fi
# implementations of the same function at runtime. This is slightly more
# efficient than using __attribute__((__constructor__)) and setting
# a function pointer.
-AC_ARG_ENABLE([ifunc], [AS_HELP_STRING([--disable-ifunc],
- [do not use __attribute__((__ifunc__()))])],
- [], [enable_ifunc=yes])
-
-if test "x$enable_ifunc" = xyes ; then
+AC_ARG_ENABLE([ifunc], [AS_HELP_STRING([--enable-ifunc],
+ [Use __attribute__((__ifunc__())). Enabled by default on
+ GNU/Linux (glibc) and FreeBSD.])],
+ [], [enable_ifunc=auto])
+
+# When enable_ifunc is 'auto', allow the use of __attribute__((__ifunc__()))
+# if compiler support is detected and we are building for GNU/Linux (glibc)
+# or FreeBSD. uClibc and musl don't support ifunc in their dynamic linkers
+# but some compilers still accept the attribute when compiling for these
+# C libraries, which results in broken binaries. That's why we need to
+# check which libc is being used.
+if test "x$enable_ifunc" = xauto ; then
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_MSG_CHECKING([if __attribute__((__ifunc__())) can be used])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+ /*
+ * Force a compilation error when not using glibc on Linux
+ * or if we are not using FreeBSD. uClibc will define
+ * __GLIBC__ but does not support ifunc, so we must have
+ * an extra check to disable with uClibc.
+ */
+ #if defined(__linux__)
+ # include <features.h>
+ # if !defined(__GLIBC__) || defined(__UCLIBC__)
+ compile error
+ # endif
+ #elif !defined(__FreeBSD__)
+ compile error
+ #endif
+
static void func(void) { return; }
static void (*resolve_func (void)) (void) { return func; }
void func_ifunc (void)
@@ -891,23 +913,28 @@ if test "x$enable_ifunc" = xyes ; then
void make_clang_quiet(void);
void make_clang_quiet(void) { resolve_func()(); }
]])], [
- AC_DEFINE([HAVE_FUNC_ATTRIBUTE_IFUNC], [1],
+ enable_ifunc=yes
+ ], [
+ enable_ifunc=no
+ ])
+
+ AC_MSG_RESULT([$enable_ifunc])
+
+ CFLAGS="$OLD_CFLAGS"
+fi
+
+if test "x$enable_ifunc" = xyes ; then
+ AC_DEFINE([HAVE_FUNC_ATTRIBUTE_IFUNC], [1],
[Define to 1 if __attribute__((__ifunc__()))
is supported for functions.])
- AC_MSG_RESULT([yes])
- # ifunc explicitly does not work with -fsanitize=address.
- # If configured, it will result in a liblzma build that
- # will fail when liblzma is loaded at runtime (when the
- # ifunc resolver executes).
- AS_CASE([$CFLAGS], [*-fsanitize=*], [AC_MSG_ERROR([
+ # ifunc explicitly does not work with -fsanitize=address.
+ # If configured, it will result in a liblzma build that will fail
+ # when liblzma is loaded at runtime (when the ifunc resolver
+ # executes).
+ AS_CASE([$CFLAGS], [*-fsanitize=*], [AC_MSG_ERROR([
CFLAGS contains '-fsanitize=' which is incompatible with ifunc.
Use --disable-ifunc when using '-fsanitize'.])])
- ], [
- AC_MSG_RESULT([no])
- ])
-
- CFLAGS="$OLD_CFLAGS"
fi