[m-rev.] for review: Further prevent use of non-local gotos with PIC on x86 with GCC 5+.

Peter Wang novalazy at gmail.com
Mon May 10 13:38:36 AEST 2021


configure.ac:
    Run the C compiler to check if it actually targets x86-64.
    Previously we assumed if $host is x86_64 then the C compiler will be
    targeting x86-64, but that is not true if gcc -m32 or gcc -mx32 is
    used.

    Then, as before, if the C compiler targets x86 and dynamic linking
    is enabled (except on Windows) and GCC is version 5+ then disable
    selection of any grades that use gcc labels.

runtime/mercury_goto.h:
    Report an error if the user tries to use non-local gotos with PIC
    on x86 with GCC 5+.

README.x86:
    Document the issue.

README.md:
    Add reference to README.x86.

diff --git a/README.md b/README.md
index 9e380f4e2..ec91f5c09 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,7 @@ Specific information is contained in individual README files:
         [MinGW](README.MinGW),
         [Cygwin](README.Cygwin))
       * [Cross compilation](README.cross)
+      * [x86](README.x86)
 
 ## Other information
 
diff --git a/README.x86 b/README.x86
new file mode 100644
index 000000000..d35f17a34
--- /dev/null
+++ b/README.x86
@@ -0,0 +1,24 @@
+Due to improvements in GCC, the following combination is not supported:
+
+  - GCC version 5 and above
+  - x86
+  - PIC (position-independent code), i.e. dynamic linking
+  - low-level C grades using non-local gotos, i.e. asm_fast.*
+
+The configure script will not select asm_fast grades when that combination is
+detected. If you try to use that combination by selecting an asm_fast grade
+manually, you will encounter compile time errors.
+
+We recommend using high-level C grades (hlc.*) on x86. If you require a
+low-level C grade, e.g. for debugging, then you can use a reg.* grade.
+
+If you must use an asm_fast grade, you will need to tell the C compiler not to
+generate position-independent code, and disable building of shared libraries.
+Alternatively, you could downgrade to gcc 4.9.
+
+Note that Windows is unaffected by this issue as Windows does not use PIC,
+and we do not yet support shared libraries (DLLs) on Windows anyway.
+
+Also note x86-64 is not affected by this issue, only x86.
+
+<https://bugs.mercurylang.org/view.php?id=453>
diff --git a/configure.ac b/configure.ac
index e135d91e0..234682f46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2339,7 +2339,7 @@ case "$ac_cv_prog_gcc" in yes)
         mips-*)
             CFLAGS_FOR_GOTOS="$CFLAGS_FOR_GOTOS -fomit-frame-pointer"
             ;;
-        i*86-*)
+        i*86-*|x86_64*)
             # On x86-64 and x86, GCC labels do not work correctly with
             # -ftree-dominator-opts.
             CFLAGS_FOR_GOTOS="$CFLAGS_FOR_GOTOS $CFLAGS_FOR_NO_TREE_DOMINATOR_OPTS"
@@ -2354,32 +2354,47 @@ case "$ac_cv_prog_gcc" in yes)
             # libraries, accepting whatever drawbacks that entails.
             #
             # XXX Not all platforms use PIC for dynamic linking, so this should
-            # be contingent on CFLAGS_FOR_PIC which is set further down. 
+            # be contingent on CFLAGS_FOR_PIC which is set further down.
             #
+            allow_pic_nonlocal_gotos=no
             case $C_COMPILER_TYPE in
-                gcc_3_*|gcc_4_*) ;;
-                gcc_*)
-                    if test "$mercury_cv_enable_shared_libs" = yes
-                    then
-                        # XXX Make an exception for Windows since it doesn't use
-                        # PIC and we don't yet support DLLs anyway.
-                        case "$host" in
-                            *cygwin*|*mingw*)
-                                ;;
-                            *)
-                                mercury_cv_asm_labels=no
-                                mercury_cv_gcc_labels=no
-                                ;;
-                        esac
-                    fi
+                gcc_3_*|gcc_4_*)
+                    allow_pic_nonlocal_gotos=yes
                     ;;
             esac
-            ;;
-        x86_64*)
-            # On x86-64 and x86, GCC labels do not work correctly with
-            # -ftree-dominator-opts.
-            CFLAGS_FOR_GOTOS="$CFLAGS_FOR_GOTOS $CFLAGS_FOR_NO_TREE_DOMINATOR_OPTS"
-            CFLAGS_FOR_REGS="-fno-builtin -fno-omit-frame-pointer"
+            case "$host" in
+                *cygwin*|*mingw*)
+                    # Windows doesn't use PIC and we don't yet support DLLs
+                    # anyway.
+                    allow_pic_nonlocal_gotos=yes
+                    ;;
+                *)
+                    # Run the compiler to check what it is targeting.
+                    # Even if $host is x86_64, gcc -m32 or gcc -mx32
+                    # may be used to target x86.
+                    AC_MSG_CHECKING(whether C compiler targets x86_64)
+                    AC_CACHE_VAL(mercury_cv_target_x86_64,
+                        AC_TRY_COMPILE(
+                            [],
+                            [
+                                #ifndef __x86_64__
+                                #error "Target is not x86_64"
+                                #endif
+                            ],
+                            [mercury_cv_target_x86_64=yes],
+                            [mercury_cv_target_x86_64=no])
+                    )
+                    AC_MSG_RESULT($mercury_cv_target_x86_64)
+                    allow_pic_nonlocal_gotos="$mercury_cv_target_x86_64"
+                    ;;
+            esac
+            if test "$mercury_cv_enable_shared_libs" = yes && \
+                test "$allow_pic_nonlocal_gotos" = no
+            then
+                MERCURY_MSG("gcc labels do not work with PIC on x86")
+                mercury_cv_asm_labels=no
+                mercury_cv_gcc_labels=no
+            fi
             ;;
         rs6000-*)
             MERCURY_MSG("gcc labels do not work on the RS/6000")
diff --git a/runtime/mercury_goto.h b/runtime/mercury_goto.h
index da54c4432..1b412c38c 100644
--- a/runtime/mercury_goto.h
+++ b/runtime/mercury_goto.h
@@ -401,6 +401,10 @@
 
     #if defined(__i386__)
 
+      #if defined(MR_USE_GCC_NONLOCAL_GOTOS) && (__GNUC__ >= 5)
+          #error "Non-local jumps into x86 PIC will not work with GCC 5+"
+      #endif
+
       #define MR_EBX "%%ebx"
 
       #define MR_INLINE_ASM_FIXUP_REGS                                   \
-- 
2.30.0



More information about the reviews mailing list