From d2a284ab461681919cadaed394adebe42c4cc7bb Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 31 Mar 2019 16:00:34 -0400 Subject: configure: Always use AC_LINK_ELSEIF when testing against assembler This fixes #16440, where the build system incorrectly concluded that the `.subsections_via_symbols` assembler directive was supported on a Linux system. This was caused by the fact that gcc was invoked with `-flto`; when so-configured gcc does not call the assembler but rather simply serialises its AST for compilation during the final link. This is described in Note [autoconf assembler checks and -flto]. (cherry picked from commit 7b090b53fea065d2cfd967ea919426af9ba8d737) --- aclocal.m4 | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index 87b7e8519a..6eda094315 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -288,11 +288,31 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS], esac } + dnl Note [autoconf assembler checks and -flto] + dnl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + dnl + dnl Autoconf's AC_COMPILE_IFELSE macro is fragile in the case of checks + dnl which require that the assembler is run. Specifically, GCC does not run + dnl the assembler if invoked with `-c -flto`; it merely dumps its internal + dnl AST to the object file, to be compiled and assembled during the final + dnl link. + dnl + dnl This can cause configure checks like that for the + dnl .subsections_via_symbols directive to pass unexpected (see #16440), + dnl leading the build system to incorrectly conclude that the directive is + dnl supported. + dnl + dnl For this reason, it is important that configure checks that rely on the + dnl assembler failing use AC_LINK_IFELSE rather than AC_COMPILE_IFELSE, + dnl ensuring that the assembler sees the check. + dnl + dnl ** check for Apple-style dead-stripping support dnl (.subsections-via-symbols assembler directive) AC_MSG_CHECKING(for .subsections_via_symbols) - AC_COMPILE_IFELSE( + dnl See Note [autoconf assembler checks and -flto] + AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [__asm__ (".subsections_via_symbols");])], [AC_MSG_RESULT(yes) HaskellHaveSubsectionsViaSymbols=True @@ -305,8 +325,9 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS], dnl ** check for .ident assembler directive AC_MSG_CHECKING(whether your assembler supports .ident directive) - AC_COMPILE_IFELSE( - [AC_LANG_SOURCE([__asm__ (".ident \"GHC x.y.z\"");])], + dnl See Note [autoconf assembler checks and -flto] + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([__asm__ (".ident \"GHC x.y.z\"");], [])], [AC_MSG_RESULT(yes) HaskellHaveIdentDirective=True], [AC_MSG_RESULT(no) @@ -330,8 +351,15 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS], ;; esac AC_MSG_CHECKING(for GNU non-executable stack support) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([__asm__ (".section .note.GNU-stack,\"\",$progbits");], [0])], + dnl See Note [autoconf assembler checks and -flto] + AC_LINK_IFELSE( + dnl the `main` function is placed after the .note.GNU-stack directive + dnl so we need to ensure that the active segment is correctly set, + dnl otherwise `main` will be placed in the wrong segment. + [AC_LANG_PROGRAM([ + __asm__ (".section .note.GNU-stack,\"\",$progbits"); + __asm__ (".section .text"); + ], [0])], [AC_MSG_RESULT(yes) HaskellHaveGnuNonexecStack=True], [AC_MSG_RESULT(no) -- cgit v1.2.1