On RISC-V, large code model is only compatible with position-depedent
code. However, the configure script checks availability of
-mcmodel=large before determining whether PIC/PIE is enabled, and
disable them.

This is problematic with toolchains that enable PIE by default, where
check for -mcmodel=large will always fail with,

        cc1: sorry, unimplemented: code model 'large' with '-fPIC'

and -mcmodel=medany will be silently used instead, causing relocation
failures at runtime with some memory layouts since -mcmodel=medany
requires all data and code to stay within a contiguous 4GiB range.

Let's defer the check for -mcmodel=large until PIC/PIE is ensured
disabled.

Fixes: f1957dc8a334 ("RISC-V: Add to build system")
Reported-by: Han Gao <[email protected]>
Signed-off-by: Yao Zi <[email protected]>
---
 configure.ac | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

This problem is known to be discovered independently by developers from
Ubuntu and Sophgo, too. However I don't have their accurate information,
so only Han Gao is listed in Reported-by tag.

diff --git a/configure.ac b/configure.ac
index a282bf7bfbc7..a833c7612734 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1543,21 +1543,6 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
 
 LDFLAGS="$TARGET_LDFLAGS"
 
-if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test 
"$target_cpu" = riscv64 ; then
-  # Use large model to support 4G memory
-  AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
-    CFLAGS="$TARGET_CFLAGS -mcmodel=large"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-                     [grub_cv_cc_mcmodel=yes],
-                     [grub_cv_cc_mcmodel=no])
-  ])
-  if test "x$grub_cv_cc_mcmodel" = xyes; then
-    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
-  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
-    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
-  fi
-fi
-
 if test "$target_cpu"-"$platform" = x86_64-efi; then
   # EFI writes to stack below %rsp, we must not use the red zone
   AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, 
[
@@ -1666,6 +1651,21 @@ fi]
 
 CFLAGS="$TARGET_CFLAGS"
 
+if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test 
"$target_cpu" = riscv64 ; then
+  # Use large model to support 4G memory
+  AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
+    CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+                     [grub_cv_cc_mcmodel=yes],
+                     [grub_cv_cc_mcmodel=no])
+  ])
+  if test "x$grub_cv_cc_mcmodel" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+  elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
+  fi
+fi
+
 # Stack smashing protector.
 grub_CHECK_STACK_PROTECTOR
 AC_ARG_ENABLE([stack-protector],
-- 
2.51.2


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to