a5bd9f6
From 8968eeb2ff92930128a5d9820157de08876ab489 Mon Sep 17 00:00:00 2001
a5bd9f6
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
a5bd9f6
Date: Fri, 19 Apr 2013 15:05:11 +0200
a5bd9f6
Subject: [PATCH 325/364] 	* grub-core/kern/elfXX.c (grub_elfXX_load):
a5bd9f6
 Handle 	GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS. 
a5bd9f6
 * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32), 
a5bd9f6
 (grub_linux_load64): Mask out 2 high bits.
a5bd9f6
a5bd9f6
---
a5bd9f6
 ChangeLog                                 |  7 +++++++
a5bd9f6
 grub-core/kern/elfXX.c                    | 16 ++++++++++++++--
a5bd9f6
 grub-core/loader/powerpc/ieee1275/linux.c |  4 ++--
a5bd9f6
 include/grub/elfload.h                    |  4 ++++
a5bd9f6
 4 files changed, 27 insertions(+), 4 deletions(-)
a5bd9f6
a5bd9f6
diff --git a/ChangeLog b/ChangeLog
a5bd9f6
index 7450036..3799129 100644
a5bd9f6
--- a/ChangeLog
a5bd9f6
+++ b/ChangeLog
a5bd9f6
@@ -1,3 +1,10 @@
a5bd9f6
+2013-04-19  Vladimir Serbinenko  <phcoder@gmail.com>
a5bd9f6
+
a5bd9f6
+	* grub-core/kern/elfXX.c (grub_elfXX_load): Handle
a5bd9f6
+	GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS.
a5bd9f6
+	* grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32),
a5bd9f6
+	(grub_linux_load64): Mask out 2 high bits.
a5bd9f6
+
a5bd9f6
 2013-04-19  Andrey Borzenkov <arvidjaar@gmail.com>
a5bd9f6
 
a5bd9f6
 	* util/grub.d/30_os-prober.in: Add onstr to linux entries in one
a5bd9f6
diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c
a5bd9f6
index b35e235..2e45449 100644
a5bd9f6
--- a/grub-core/kern/elfXX.c
a5bd9f6
+++ b/grub-core/kern/elfXX.c
a5bd9f6
@@ -101,8 +101,20 @@ grub_elfXX_load (grub_elf_t elf, const char *filename,
a5bd9f6
       continue;
a5bd9f6
 
a5bd9f6
     load_addr = (grub_addr_t) phdr->p_paddr;
a5bd9f6
-    if (load_flags & GRUB_ELF_LOAD_FLAGS_28BITS)
a5bd9f6
-      load_addr &= 0xFFFFFFF;
a5bd9f6
+    switch (load_flags & GRUB_ELF_LOAD_FLAGS_BITS)
a5bd9f6
+      {
a5bd9f6
+      case GRUB_ELF_LOAD_FLAGS_ALL_BITS:
a5bd9f6
+	break;
a5bd9f6
+      case GRUB_ELF_LOAD_FLAGS_28BITS:
a5bd9f6
+	load_addr &= 0xFFFFFFF;
a5bd9f6
+	break;
a5bd9f6
+      case GRUB_ELF_LOAD_FLAGS_30BITS:
a5bd9f6
+	load_addr &= 0x3FFFFFFF;
a5bd9f6
+	break;
a5bd9f6
+      case GRUB_ELF_LOAD_FLAGS_62BITS:
a5bd9f6
+	load_addr &= 0x3FFFFFFFFFFFFFFFULL;
a5bd9f6
+	break;
a5bd9f6
+      }
a5bd9f6
     load_addr += (grub_addr_t) load_offset;
a5bd9f6
 
a5bd9f6
     if (load_addr < load_base)
a5bd9f6
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
a5bd9f6
index cff4fd1..3356d51 100644
a5bd9f6
--- a/grub-core/loader/powerpc/ieee1275/linux.c
a5bd9f6
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
a5bd9f6
@@ -204,7 +204,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename)
a5bd9f6
   linux_addr = seg_addr;
a5bd9f6
 
a5bd9f6
   /* Now load the segments into the area we claimed.  */
a5bd9f6
-  return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
a5bd9f6
+  return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_30BITS, 0, 0);
a5bd9f6
 }
a5bd9f6
 
a5bd9f6
 static grub_err_t
a5bd9f6
@@ -238,7 +238,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename)
a5bd9f6
   linux_addr = seg_addr;
a5bd9f6
 
a5bd9f6
   /* Now load the segments into the area we claimed.  */
a5bd9f6
-  return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0);
a5bd9f6
+  return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_62BITS, 0, 0);
a5bd9f6
 }
a5bd9f6
 
a5bd9f6
 static grub_err_t
a5bd9f6
diff --git a/include/grub/elfload.h b/include/grub/elfload.h
a5bd9f6
index f854d0b..9a7ae4e 100644
a5bd9f6
--- a/include/grub/elfload.h
a5bd9f6
+++ b/include/grub/elfload.h
a5bd9f6
@@ -53,7 +53,11 @@ enum grub_elf_load_flags
a5bd9f6
   {
a5bd9f6
     GRUB_ELF_LOAD_FLAGS_NONE = 0,
a5bd9f6
     GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC = 1,
a5bd9f6
+    GRUB_ELF_LOAD_FLAGS_BITS = 6,
a5bd9f6
+    GRUB_ELF_LOAD_FLAGS_ALL_BITS = 0,
a5bd9f6
     GRUB_ELF_LOAD_FLAGS_28BITS = 2,
a5bd9f6
+    GRUB_ELF_LOAD_FLAGS_30BITS = 4,
a5bd9f6
+    GRUB_ELF_LOAD_FLAGS_62BITS = 6,
a5bd9f6
   };
a5bd9f6
 grub_err_t grub_elf32_load (grub_elf_t, const char *filename,
a5bd9f6
 			    void *load_offset, enum grub_elf_load_flags flags, grub_addr_t *,
a5bd9f6
-- 
a5bd9f6
1.8.1.4
a5bd9f6