Support grub-emu on x32 (ILP32 but with x86-64 instruction set)
authorColin Watson <cjwatson@ubuntu.com>
Sun, 7 Sep 2014 22:04:35 +0000 (23:04 +0100)
committerColin Watson <cjwatson@ubuntu.com>
Sun, 7 Sep 2014 22:04:50 +0000 (23:04 +0100)
* configure.ac: Remove -m64 from checks for -mcmodel=large and
-mno-red-zone.  These are always either unnecessary (x86_64-emu) or
already in TARGET_CFLAGS at this point, and they produce incorrect
results when building for x32.
* grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Cast
pointers to Elf64_Xword via grub_addr_t, in order to work on x32.
* include/grub/x86_64/types.h (GRUB_TARGET_SIZEOF_VOID_P,
GRUB_TARGET_SIZEOF_LONG): Define to 4 on x32.

ChangeLog
configure.ac
grub-core/kern/x86_64/dl.c
include/grub/x86_64/types.h

index 4e422b8..572ee50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-09-07  Colin Watson  <cjwatson@ubuntu.com>
+
+       Support grub-emu on x32 (ILP32 but with x86-64 instruction set)
+
+       * configure.ac: Remove -m64 from checks for -mcmodel=large and
+       -mno-red-zone.  These are always either unnecessary (x86_64-emu) or
+       already in TARGET_CFLAGS at this point, and they produce incorrect
+       results when building for x32.
+       * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Cast
+       pointers to Elf64_Xword via grub_addr_t, in order to work on x32.
+       * include/grub/x86_64/types.h (GRUB_TARGET_SIZEOF_VOID_P,
+       GRUB_TARGET_SIZEOF_LONG): Define to 4 on x32.
+
 2014-09-07  Colin Watson  <cjwatson@ubuntu.com>
 
        * configure.ac: Remove several unnecessary semicolons.
index a3610e1..8662bac 100644 (file)
@@ -862,7 +862,7 @@ LDFLAGS="$TARGET_LDFLAGS"
 if test "$target_cpu" = x86_64 || test "$target_cpu-$platform" = sparc64-emu ; then
   # Use large model to support 4G memory
   AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
-    CFLAGS="$TARGET_CFLAGS -m64 -mcmodel=large"
+    CFLAGS="$TARGET_CFLAGS -mcmodel=large"
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
                      [grub_cv_cc_mcmodel=yes],
                      [grub_cv_cc_mcmodel=no])
@@ -877,7 +877,7 @@ 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, [
-    CFLAGS="$TARGET_CFLAGS -m64 -mno-red-zone"
+    CFLAGS="$TARGET_CFLAGS -mno-red-zone"
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
                      [grub_cv_cc_no_red_zone=yes],
                      [grub_cv_cc_no_red_zone=no])
index 6cb88bf..4406906 100644 (file)
@@ -73,7 +73,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
          {
            grub_int64_t value;
            value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
-             (Elf64_Xword) seg->addr - rel->r_offset;
+             (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset;
            if (value != (grub_int32_t) value)
              return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
            *addr32 = value;
@@ -83,7 +83,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
        case R_X86_64_PC64:
          {
            *addr64 += rel->r_addend + sym->st_value -
-             (Elf64_Xword) seg->addr - rel->r_offset;
+             (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset;
          }
          break;
 
index fec9109..0bbdc6d 100644 (file)
 #define GRUB_TYPES_CPU_HEADER  1
 
 /* The size of void *.  */
+#ifdef __ILP32__
+#define GRUB_TARGET_SIZEOF_VOID_P      4
+#else
 #define GRUB_TARGET_SIZEOF_VOID_P      8
+#endif
 
 /* The size of long.  */
-#ifdef __MINGW32__
+#if defined(__MINGW32__) || defined(__ILP32__)
 #define GRUB_TARGET_SIZEOF_LONG                4
 #else
 #define GRUB_TARGET_SIZEOF_LONG                8