8c6b1ac
From 2a5a532c0047d4eff90175936b220b638cce1013 Mon Sep 17 00:00:00 2001
8c6b1ac
From: Colin Watson <cjwatson@ubuntu.com>
8c6b1ac
Date: Sun, 7 Sep 2014 23:04:35 +0100
8c6b1ac
Subject: [PATCH 097/506] Support grub-emu on x32 (ILP32 but with x86-64
8c6b1ac
 instruction set)
8c6b1ac
8c6b1ac
* configure.ac: Remove -m64 from checks for -mcmodel=large and
8c6b1ac
-mno-red-zone.  These are always either unnecessary (x86_64-emu) or
8c6b1ac
already in TARGET_CFLAGS at this point, and they produce incorrect
8c6b1ac
results when building for x32.
8c6b1ac
* grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Cast
8c6b1ac
pointers to Elf64_Xword via grub_addr_t, in order to work on x32.
8c6b1ac
* include/grub/x86_64/types.h (GRUB_TARGET_SIZEOF_VOID_P,
8c6b1ac
GRUB_TARGET_SIZEOF_LONG): Define to 4 on x32.
8c6b1ac
---
8c6b1ac
 ChangeLog                   | 13 +++++++++++++
8c6b1ac
 configure.ac                |  4 ++--
8c6b1ac
 grub-core/kern/x86_64/dl.c  |  4 ++--
8c6b1ac
 include/grub/x86_64/types.h |  6 +++++-
8c6b1ac
 4 files changed, 22 insertions(+), 5 deletions(-)
8c6b1ac
8c6b1ac
diff --git a/ChangeLog b/ChangeLog
8c6b1ac
index 4e422b8..572ee50 100644
8c6b1ac
--- a/ChangeLog
8c6b1ac
+++ b/ChangeLog
8c6b1ac
@@ -1,5 +1,18 @@
8c6b1ac
 2014-09-07  Colin Watson  <cjwatson@ubuntu.com>
8c6b1ac
 
8c6b1ac
+	Support grub-emu on x32 (ILP32 but with x86-64 instruction set)
8c6b1ac
+
8c6b1ac
+	* configure.ac: Remove -m64 from checks for -mcmodel=large and
8c6b1ac
+	-mno-red-zone.  These are always either unnecessary (x86_64-emu) or
8c6b1ac
+	already in TARGET_CFLAGS at this point, and they produce incorrect
8c6b1ac
+	results when building for x32.
8c6b1ac
+	* grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Cast
8c6b1ac
+	pointers to Elf64_Xword via grub_addr_t, in order to work on x32.
8c6b1ac
+	* include/grub/x86_64/types.h (GRUB_TARGET_SIZEOF_VOID_P,
8c6b1ac
+	GRUB_TARGET_SIZEOF_LONG): Define to 4 on x32.
8c6b1ac
+
8c6b1ac
+2014-09-07  Colin Watson  <cjwatson@ubuntu.com>
8c6b1ac
+
8c6b1ac
 	* configure.ac: Remove several unnecessary semicolons.
8c6b1ac
 
8c6b1ac
 2014-08-25  Colin Watson  <cjwatson@ubuntu.com>
8c6b1ac
diff --git a/configure.ac b/configure.ac
8c6b1ac
index a3610e1..8662bac 100644
8c6b1ac
--- a/configure.ac
8c6b1ac
+++ b/configure.ac
8c6b1ac
@@ -862,7 +862,7 @@ LDFLAGS="$TARGET_LDFLAGS"
8c6b1ac
 if test "$target_cpu" = x86_64 || test "$target_cpu-$platform" = sparc64-emu ; then
8c6b1ac
   # Use large model to support 4G memory
8c6b1ac
   AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
8c6b1ac
-    CFLAGS="$TARGET_CFLAGS -m64 -mcmodel=large"
8c6b1ac
+    CFLAGS="$TARGET_CFLAGS -mcmodel=large"
8c6b1ac
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
8c6b1ac
 		      [grub_cv_cc_mcmodel=yes],
8c6b1ac
 		      [grub_cv_cc_mcmodel=no])
8c6b1ac
@@ -877,7 +877,7 @@ fi
8c6b1ac
 if test "$target_cpu"-"$platform" = x86_64-efi; then
8c6b1ac
   # EFI writes to stack below %rsp, we must not use the red zone
8c6b1ac
   AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [
8c6b1ac
-    CFLAGS="$TARGET_CFLAGS -m64 -mno-red-zone"
8c6b1ac
+    CFLAGS="$TARGET_CFLAGS -mno-red-zone"
8c6b1ac
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
8c6b1ac
 		      [grub_cv_cc_no_red_zone=yes],
8c6b1ac
 		      [grub_cv_cc_no_red_zone=no])
8c6b1ac
diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
8c6b1ac
index 6cb88bf..4406906 100644
8c6b1ac
--- a/grub-core/kern/x86_64/dl.c
8c6b1ac
+++ b/grub-core/kern/x86_64/dl.c
8c6b1ac
@@ -73,7 +73,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
8c6b1ac
 	  {
8c6b1ac
 	    grub_int64_t value;
8c6b1ac
 	    value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
8c6b1ac
-	      (Elf64_Xword) seg->addr - rel->r_offset;
8c6b1ac
+	      (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset;
8c6b1ac
 	    if (value != (grub_int32_t) value)
8c6b1ac
 	      return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
8c6b1ac
 	    *addr32 = value;
8c6b1ac
@@ -83,7 +83,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
8c6b1ac
 	case R_X86_64_PC64:
8c6b1ac
 	  {
8c6b1ac
 	    *addr64 += rel->r_addend + sym->st_value -
8c6b1ac
-	      (Elf64_Xword) seg->addr - rel->r_offset;
8c6b1ac
+	      (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset;
8c6b1ac
 	  }
8c6b1ac
 	  break;
8c6b1ac
 
8c6b1ac
diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h
8c6b1ac
index fec9109..0bbdc6d 100644
8c6b1ac
--- a/include/grub/x86_64/types.h
8c6b1ac
+++ b/include/grub/x86_64/types.h
8c6b1ac
@@ -20,10 +20,14 @@
8c6b1ac
 #define GRUB_TYPES_CPU_HEADER	1
8c6b1ac
 
8c6b1ac
 /* The size of void *.  */
8c6b1ac
+#ifdef __ILP32__
8c6b1ac
+#define GRUB_TARGET_SIZEOF_VOID_P	4
8c6b1ac
+#else
8c6b1ac
 #define GRUB_TARGET_SIZEOF_VOID_P	8
8c6b1ac
+#endif
8c6b1ac
 
8c6b1ac
 /* The size of long.  */
8c6b1ac
-#ifdef __MINGW32__
8c6b1ac
+#if defined(__MINGW32__) || defined(__ILP32__)
8c6b1ac
 #define GRUB_TARGET_SIZEOF_LONG		4
8c6b1ac
 #else
8c6b1ac
 #define GRUB_TARGET_SIZEOF_LONG		8
8c6b1ac
-- 
8c6b1ac
2.4.3
8c6b1ac