]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
made relocator more portable
authorphcoder <phcoder@debian.bg45.phnet>
Sun, 11 Oct 2009 20:20:55 +0000 (22:20 +0200)
committerphcoder <phcoder@debian.bg45.phnet>
Sun, 11 Oct 2009 20:20:55 +0000 (22:20 +0200)
lib/i386/relocator.c
lib/relocator.c [new file with mode: 0644]

index 3f0a40a27aac9c8401ea19003197528f2eddb792..84832eb02ec64ba6c9a64874946359181ab196b4 100644 (file)
@@ -54,112 +54,51 @@ extern grub_uint32_t grub_relocator32_backward_esp;
 
 #define RELOCATOR_SIZEOF(x)    (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start)
 #define RELOCATOR_ALIGN 16
+#define PREFIX(x) grub_relocator32_ ## x
 
-void *
-grub_relocator32_alloc (grub_size_t size)
+static void
+write_relocator_bw (void *ptr, void *src, grub_uint32_t dest,
+                   grub_size_t size, struct grub_relocator32_state state)
 {
-  char *playground;
-
-  playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
-                           + size
-                           + (RELOCATOR_SIZEOF (backward) +
-                              RELOCATOR_ALIGN));
-  if (!playground)
-    return 0;
-
-  *(grub_size_t *) playground = size;
-
-  return playground + RELOCATOR_SIZEOF (forward);
-}
-
-void *
-grub_relocator32_realloc (void *relocator, grub_size_t size)
-{
-  char *playground;
-
-  playground = (char *) relocator - RELOCATOR_SIZEOF (forward);
-
-  playground = grub_realloc (playground,
-                            (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
-                            + size
-                            + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN));
-  if (!playground)
-    return 0;
-
-  *(grub_size_t *) playground = size;
-
-  return playground + RELOCATOR_SIZEOF (forward);
-}
+  void (*entry) ();
 
-void
-grub_relocator32_free (void *relocator)
-{
-  if (relocator)
-    grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward));
+  grub_relocator32_backward_dest = dest;
+  grub_relocator32_backward_src = PTR_TO_UINT64 (src);
+  grub_relocator32_backward_size = size;
+
+  grub_relocator32_backward_eax = state.eax;
+  grub_relocator32_backward_ebx = state.ebx;
+  grub_relocator32_backward_ecx = state.ecx;
+  grub_relocator32_backward_edx = state.edx;
+  grub_relocator32_backward_eip = state.eip;
+  grub_relocator32_backward_esp = state.esp;
+
+  grub_memmove (ptr,
+               &grub_relocator32_backward_start,
+               RELOCATOR_SIZEOF (backward));
+  entry = (void (*)()) (ptr);
+  entry ();
 }
 
-
-grub_err_t
-grub_relocator32_boot (void *relocator, grub_uint32_t dest,
-                      struct grub_relocator32_state state)
+static void
+write_relocator_bw (void *ptr, void *src, grub_uint32_t dest,
+                   grub_size_t size, struct grub_relocator32_state state)
 {
-  grub_size_t size;
-  char *playground;
-  void (*entry) ();
-
-  playground = (char *) relocator - RELOCATOR_SIZEOF (forward);
-  size = *(grub_size_t *) playground;
-
-  if (UINT_TO_PTR (dest) >= relocator)
-    {
-      int overhead;
-
-      overhead =
-       ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN,
-                 RELOCATOR_ALIGN);
-      grub_relocator32_backward_dest = dest - overhead;
-      grub_relocator32_backward_src = PTR_TO_UINT64 (relocator - overhead);
-      grub_relocator32_backward_size = size + overhead;
 
-      grub_relocator32_backward_eax = state.eax;
-      grub_relocator32_backward_ebx = state.ebx;
-      grub_relocator32_backward_ecx = state.ecx;
-      grub_relocator32_backward_edx = state.edx;
-      grub_relocator32_backward_eip = state.eip;
-      grub_relocator32_backward_esp = state.esp;
-
-      grub_memmove (relocator - overhead,
-                   &grub_relocator32_backward_start,
-                   RELOCATOR_SIZEOF (backward));
-      entry = (void (*)()) (relocator - overhead);
-    }
-  else
-    {
-      int overhead;
-
-      overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN)
-       + RELOCATOR_SIZEOF (forward) - (dest + size);
-
-      grub_relocator32_forward_dest = dest;
-      grub_relocator32_forward_src = PTR_TO_UINT64 (relocator);
-      grub_relocator32_forward_size = size + overhead;
-
-      grub_relocator32_forward_eax = state.eax;
-      grub_relocator32_forward_ebx = state.ebx;
-      grub_relocator32_forward_ecx = state.ecx;
-      grub_relocator32_forward_edx = state.edx;
-      grub_relocator32_forward_eip = state.eip;
-      grub_relocator32_forward_esp = state.esp;
-
-      grub_memmove (relocator + size + overhead - RELOCATOR_SIZEOF (forward),
-                   &grub_relocator32_forward_start,
-                   RELOCATOR_SIZEOF (forward));
-      entry =
-       (void (*)()) (relocator + size + overhead -
-                     RELOCATOR_SIZEOF (forward));
-    }
+  grub_relocator32_forward_dest = dest;
+  grub_relocator32_forward_src = PTR_TO_UINT64 (src);
+  grub_relocator32_forward_size = size;
+  
+  grub_relocator32_forward_eax = state.eax;
+  grub_relocator32_forward_ebx = state.ebx;
+  grub_relocator32_forward_ecx = state.ecx;
+  grub_relocator32_forward_edx = state.edx;
+  grub_relocator32_forward_eip = state.eip;
+  grub_relocator32_forward_esp = state.esp;
+  
+  grub_memmove (ptr,
+               &grub_relocator32_forward_start,
+               RELOCATOR_SIZEOF (forward));
+  entry = (void (*)()) ptr;
   entry ();
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
 }
diff --git a/lib/relocator.c b/lib/relocator.c
new file mode 100644 (file)
index 0000000..750753b
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void *
+PREFIX (alloc) (grub_size_t size)
+{
+  char *playground;
+
+  playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
+                           + size
+                           + (RELOCATOR_SIZEOF (backward) +
+                              RELOCATOR_ALIGN));
+  if (!playground)
+    return 0;
+
+  *(grub_size_t *) playground = size;
+
+  return playground + RELOCATOR_SIZEOF (forward);
+}
+
+void *
+PREFIX (realloc) (void *relocator, grub_size_t size)
+{
+  char *playground;
+
+  playground = (char *) relocator - RELOCATOR_SIZEOF (forward);
+
+  playground = grub_realloc (playground,
+                            (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
+                            + size
+                            + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN));
+  if (!playground)
+    return 0;
+
+  *(grub_size_t *) playground = size;
+
+  return playground + RELOCATOR_SIZEOF (forward);
+}
+
+void
+PREFIX(free) (void *relocator)
+{
+  if (relocator)
+    grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward));
+}
+
+grub_err_t
+PREFIX (boot) (void *relocator, grub_uint32_t dest,
+              struct grub_relocator32_state state)
+{
+  grub_size_t size;
+  char *playground;
+
+  playground = (char *) relocator - RELOCATOR_SIZEOF (forward);
+  size = *(grub_size_t *) playground;
+
+  if (UINT_TO_PTR (dest) >= relocator)
+    {
+      int overhead;
+      void *reldest = relocator - overhead;
+      overhead =
+       ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN,
+                 RELOCATOR_ALIGN);
+      write_call_relocator_bw (relocator - overhead,
+                              relocator - overhead,
+                              dest - overhead, size + overhead, state);
+    }
+  else
+    {
+      int overhead;
+
+      overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN)
+       + RELOCATOR_SIZEOF (forward) - (dest + size);
+
+      write_call_relocator_fw (relocator + size + overhead
+                              - RELOCATOR_SIZEOF (forward),
+                              relocator, dest, size + overhead, state);
+    }
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}