]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Second part of p2v support
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 21 Apr 2010 17:13:45 +0000 (19:13 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 21 Apr 2010 17:13:45 +0000 (19:13 +0200)
15 files changed:
include/grub/relocator.h
include/grub/relocator_private.h
lib/i386/relocator.c
lib/relocator.c
loader/i386/bsd.c
loader/i386/bsdXX.c
loader/i386/linux.c
loader/i386/multiboot_mbi.c
loader/i386/pc/linux.c
loader/i386/pc/ntldr.c
loader/multiboot.c
loader/multiboot_elfxx.c
loader/multiboot_mbi2.c
loader/xnu.c
loader/xnu_resume.c

index 32bab705375444ec169a74c6a38770fed3869892..89e74608890a9511b9df48becf9aa6c99b28367b 100644 (file)
 
 #include <grub/types.h>
 #include <grub/err.h>
+#include <grub/memory.h>
 
 struct grub_relocator;
+struct grub_relocator_chunk;
+typedef const struct grub_relocator_chunk *grub_relocator_chunk_t;
 
 struct grub_relocator *grub_relocator_new (void);
 
 grub_err_t
-grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
-                                grub_addr_t target, grub_size_t size);
+grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
+                                grub_relocator_chunk_t *out,
+                                grub_phys_addr_t target, grub_size_t size);
+
+void *
+get_virtual_current_address (grub_relocator_chunk_t in);
+grub_phys_addr_t
+get_physical_target_address (grub_relocator_chunk_t in);
 
 grub_err_t
-grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src, 
-                                 grub_addr_t *target,
-                                 grub_addr_t min_addr, grub_addr_t max_addr,
+grub_relocator_alloc_chunk_align (struct grub_relocator *rel, 
+                                 grub_relocator_chunk_t *out,
+                                 grub_phys_addr_t min_addr,
+                                 grub_phys_addr_t max_addr,
                                  grub_size_t size, grub_size_t align,
                                  int preference);
 
index d12a0f05a433eb76103ae4f3043de7440ad3ba23..10e445bfe46a4b40b3ff661475ac1428ce21870f 100644 (file)
@@ -32,7 +32,7 @@ void
 grub_cpu_relocator_init (void);
 grub_err_t
 grub_relocator_prepare_relocs (struct grub_relocator *rel,
-                              void *addr,
+                              grub_addr_t addr,
                               void **relstart, grub_size_t *relsize);
 void grub_cpu_relocator_forward (void *rels, void *src, void *tgt,
                                 grub_size_t size);
index 5dd4cde75c4d721dd53819e789cbe8dc00e3b1fd..55e6b557817c25d91fcf5945e4507f062dcb75d0 100644 (file)
@@ -84,12 +84,6 @@ grub_size_t grub_relocator_jumper_size = 12;
 grub_size_t grub_relocator_jumper_size = 7;
 #endif
 
-static inline void *
-ptov (grub_addr_t a)
-{
-  return (void *) a;
-}
-
 void
 grub_cpu_relocator_init (void)
 {
@@ -154,12 +148,11 @@ grub_err_t
 grub_relocator32_boot (struct grub_relocator *rel,
                       struct grub_relocator32_state state)
 {
-  grub_phys_addr_t target;
-  void *src;
   grub_err_t err;
   void *relst;
+  grub_relocator_chunk_t ch;
 
-  err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
+  err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
                                          (0xffffffff - RELOCATOR_SIZEOF (32))
                                          + 1, RELOCATOR_SIZEOF (32), 16,
                                          GRUB_RELOCATOR_PREFERENCE_NONE);
@@ -174,9 +167,11 @@ grub_relocator32_boot (struct grub_relocator *rel,
   grub_relocator32_esp = state.esp;
   grub_relocator32_esi = state.esi;
 
-  grub_memmove (src, &grub_relocator32_start, RELOCATOR_SIZEOF (32));
+  grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start,
+               RELOCATOR_SIZEOF (32));
 
-  err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
+  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+                                      &relst, NULL);
   if (err)
     return err;
 
@@ -191,12 +186,11 @@ grub_err_t
 grub_relocator16_boot (struct grub_relocator *rel,
                       struct grub_relocator16_state state)
 {
-  grub_phys_addr_t target;
-  void *src;
   grub_err_t err;
   void *relst;
+  grub_relocator_chunk_t ch;
 
-  err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
+  err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
                                          0xa0000 - RELOCATOR_SIZEOF (16),
                                          RELOCATOR_SIZEOF (16), 16,
                                          GRUB_RELOCATOR_PREFERENCE_NONE);
@@ -216,12 +210,16 @@ grub_relocator16_boot (struct grub_relocator *rel,
 
   grub_relocator16_edx = state.edx;
 
-  grub_memmove (src, &grub_relocator16_start, RELOCATOR_SIZEOF (16));
+  grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
+               RELOCATOR_SIZEOF (16));
 
-  err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
+  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+                                      &relst, NULL);
   if (err)
     return err;
 
+  grub_printf ("%p\n", relst);
+
   asm volatile ("cli");
   ((void (*) (void)) relst) ();
 
@@ -234,12 +232,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
                       struct grub_relocator64_state state,
                       grub_addr_t min_addr, grub_addr_t max_addr)
 {
-  grub_phys_addr_t target;
-  void *src;
   grub_err_t err;
   void *relst;
+  grub_relocator_chunk_t ch;
 
-  err = grub_relocator_alloc_chunk_align (rel, &src, &target, min_addr,
+  err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
                                          max_addr - RELOCATOR_SIZEOF (64),
                                          RELOCATOR_SIZEOF (64), 16,
                                          GRUB_RELOCATOR_PREFERENCE_NONE);
@@ -255,9 +252,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
   grub_relocator64_rsi = state.rsi;
   grub_relocator64_cr3 = state.cr3;
 
-  grub_memmove (src, &grub_relocator64_start, RELOCATOR_SIZEOF (64));
+  grub_memmove (get_virtual_current_address (ch), &grub_relocator64_start,
+               RELOCATOR_SIZEOF (64));
 
-  err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
+  err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+                                      &relst, NULL);
   if (err)
     return err;
 
index b559d12eabec062752a8969ba3a145e9f6c09bc4..e43463e4d7436fedbea85921f080a98440c85f87 100644 (file)
@@ -81,6 +81,18 @@ struct grub_relocator_fw_leftover *leftovers;
 
 struct grub_relocator_extra_block *extra_blocks;
 
+void *
+get_virtual_current_address (grub_relocator_chunk_t in)
+{
+  return in->srcv;
+}
+
+grub_phys_addr_t
+get_physical_target_address (grub_relocator_chunk_t in)
+{
+  return in->target;
+}
+
 struct grub_relocator *
 grub_relocator_new (void)
 {
@@ -1126,7 +1138,8 @@ adjust_limits (struct grub_relocator *rel,
 }
 
 grub_err_t
-grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
+grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
+                                grub_relocator_chunk_t *out,
                                 grub_phys_addr_t target, grub_size_t size)
 {
   struct grub_relocator_chunk *chunk;
@@ -1221,13 +1234,14 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
   grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
                rel->chunks->next);
 
-  *src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
+  chunk->srcv = grub_map_memory (chunk->src, chunk->size);
+  *out = chunk;
   return GRUB_ERR_NONE;
 }
 
 grub_err_t
-grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
-                                 grub_phys_addr_t *target,
+grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
+                                 grub_relocator_chunk_t *out,
                                  grub_phys_addr_t min_addr,
                                  grub_phys_addr_t max_addr,
                                  grub_size_t size, grub_size_t align,
@@ -1262,8 +1276,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
       chunk->size = size;
       chunk->next = rel->chunks;
       rel->chunks = chunk;
-      *src = (void *) chunk->src;
-      *target = chunk->target;
+      chunk->srcv = grub_map_memory (chunk->src, chunk->size);
+      *out = chunk;
       return GRUB_ERR_NONE;
     }
 
@@ -1300,12 +1314,12 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
        return 0;
       candidate = ALIGN_UP (addr, align);
       if (candidate < min_addr)
-       candidate = min_addr;
-      if (candidate + size >= addr + sz
+       candidate = ALIGN_UP (min_addr, align);
+      if (candidate + size > addr + sz
          || candidate > ALIGN_DOWN (max_addr, align))
        return 0;
       if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
-       candidate = ALIGN_DOWN (addr + sz - size, align);
+       candidate = ALIGN_DOWN (min (addr + sz - size, max_addr), align);
       if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH
                     && candidate > chunk->target))
        chunk->target = candidate;
@@ -1353,8 +1367,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
   rel->chunks = chunk;
   grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
                rel->chunks->next);
-  *src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
-  *target = chunk->target;
+  chunk->srcv = grub_map_memory (chunk->src, chunk->size);
+  *out = chunk;
   return GRUB_ERR_NONE;
 }
 
@@ -1378,7 +1392,7 @@ grub_relocator_unload (struct grub_relocator *rel)
 }
 
 grub_err_t
-grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
+grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
                               void **relstart, grub_size_t *relsize)
 {
   grub_uint8_t *rels;
@@ -1395,12 +1409,12 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
                        grub_relocator_align,
                        rel->relocators_size, &movers_chunk, 1, 1))
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
-  rels = rels0 = movers_chunk.srcv;
+  rels = rels0 = grub_map_memory (movers_chunk.src, movers_chunk.size);
 
   if (relsize)
     *relsize = rel->relocators_size;
 
-  grub_dprintf ("relocator", "Relocs allocated\n");
+  grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv);
   
   {
     unsigned i;
index cfd10713de5439f20e8f4b9c639ba238251b4ef6..1b2fadd80629f44c07b725d124ff12aca1324e3f 100644 (file)
@@ -606,10 +606,14 @@ grub_freebsd_boot (void)
   if (is_64bit)
     p_size += 4096 * 3;
 
-  err = grub_relocator_alloc_chunk_addr (relocator, (void **) &p,
-                                        kern_end, p_size);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          kern_end, p_size);
+    if (err)
+      return err;
+    p = get_virtual_current_address (ch);
+  }
   p_target = kern_end;
   p0 = p;
   kern_end += p_size;
@@ -682,14 +686,18 @@ grub_freebsd_boot (void)
       grub_uint32_t *stack;
       grub_addr_t stack_target;
 
-      err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
-                                             &stack_target,
-                                             0x10000, 0x90000,
-                                             3 * sizeof (grub_uint32_t)
-                                             + sizeof (bi), 4,
-                                             GRUB_RELOCATOR_PREFERENCE_NONE);
-      if (err)
-       return err;
+      {
+       grub_relocator_chunk_t ch;
+       err = grub_relocator_alloc_chunk_align (relocator, &ch,
+                                               0x10000, 0x90000,
+                                               3 * sizeof (grub_uint32_t)
+                                               + sizeof (bi), 4,
+                                               GRUB_RELOCATOR_PREFERENCE_NONE);
+       if (err)
+         return err;
+       stack = get_virtual_current_address (ch);
+       stack_target = get_physical_target_address (ch);
+      }
 
 #ifdef GRUB_MACHINE_EFI
       err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@@ -714,14 +722,19 @@ grub_freebsd_boot (void)
       struct grub_relocator32_state state;
       grub_uint32_t *stack;
       grub_addr_t stack_target;
-      err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
-                                             &stack_target,
-                                             0x10000, 0x90000,
-                                             9 * sizeof (grub_uint32_t)
-                                             + sizeof (bi), 4,
-                                             GRUB_RELOCATOR_PREFERENCE_NONE);
-      if (err)
-       return err;
+
+      {
+       grub_relocator_chunk_t ch;
+       err = grub_relocator_alloc_chunk_align (relocator, &ch,
+                                               0x10000, 0x90000,
+                                               9 * sizeof (grub_uint32_t)
+                                               + sizeof (bi), 4,
+                                               GRUB_RELOCATOR_PREFERENCE_NONE);
+       if (err)
+         return err;
+       stack = get_virtual_current_address (ch);
+       stack_target = get_physical_target_address (ch);
+      }
 
 #ifdef GRUB_MACHINE_EFI
       err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@@ -772,12 +785,16 @@ grub_openbsd_boot (void)
   }
 
   buf_target = GRUB_BSD_TEMP_BUFFER - 9 * sizeof (grub_uint32_t);
-  err = grub_relocator_alloc_chunk_addr (relocator, &buf0,
-                                        buf_target, tag_buf_len
-                                        + sizeof (struct grub_openbsd_bootargs)
-                                        + 9 * sizeof (grub_uint32_t));
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch, buf_target,
+                                          tag_buf_len
+                                          + sizeof (struct grub_openbsd_bootargs)
+                                          + 9 * sizeof (grub_uint32_t));
+    if (err)
+      return err;
+    buf0 = get_virtual_current_address (ch);
+  }
 
   stack = (grub_uint32_t *) buf0;
   arg0 = curarg = stack + 9;
@@ -976,12 +993,16 @@ grub_netbsd_boot (void)
   }
 
   arg_target = kern_end;
-  err = grub_relocator_alloc_chunk_addr (relocator, &curarg,
-                                        arg_target, tag_buf_len
-                                        + sizeof (struct grub_netbsd_bootinfo)
-                                        + tag_count * sizeof (grub_uint32_t));
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          arg_target, tag_buf_len
+                                          + sizeof (struct grub_netbsd_bootinfo)
+                                          + tag_count * sizeof (grub_uint32_t));
+    if (err)
+      return err;
+    curarg = get_virtual_current_address (ch);
+  }
 
   arg0 = curarg;
   bootinfo = (void *) ((grub_uint8_t *) arg0 + tag_buf_len);
@@ -1004,12 +1025,16 @@ grub_netbsd_boot (void)
       }
   }
 
-  err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack,
-                                         &stack_target, 0x10000, 0x90000,
-                                         7 * sizeof (grub_uint32_t), 4,
-                                         GRUB_RELOCATOR_PREFERENCE_NONE);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000,
+                                           7 * sizeof (grub_uint32_t), 4,
+                                           GRUB_RELOCATOR_PREFERENCE_NONE);
+    if (err)
+      return err;
+    stack = get_virtual_current_address (ch);
+    stack_target = get_physical_target_address (ch);
+  }
 
 #ifdef GRUB_MACHINE_EFI
   err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
@@ -1107,10 +1132,15 @@ grub_bsd_load_aout (grub_file_t file)
   if (!relocator)
     return grub_errno;
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
-                                        kern_start, kern_end - kern_start);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          kern_start, kern_end - kern_start);
+    if (err)
+      return err;
+    kern_chunk_src = get_virtual_current_address (ch);
+  }
 
   return grub_aout_load (file, ofs, kern_chunk_src,
                         ah.aout32.a_text + ah.aout32.a_data,
@@ -1210,15 +1240,19 @@ grub_bsd_load_elf (grub_elf_t elf)
 
   if (grub_elf_is_elf32 (elf))
     {
+      grub_relocator_chunk_t ch;
+
       entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
       err = grub_elf32_phdr_iterate (elf, grub_bsd_elf32_size_hook, NULL);
       if (err)
        return err;
-      err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
+      err = grub_relocator_alloc_chunk_addr (relocator, &ch,
                                             kern_start, kern_end - kern_start);
       if (err)
        return err;
 
+      kern_chunk_src = get_virtual_current_address (ch);
+
       return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
     }
   else if (grub_elf_is_elf64 (elf))
@@ -1246,10 +1280,15 @@ grub_bsd_load_elf (grub_elf_t elf)
 
       grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n",
                    (unsigned long) kern_start, (unsigned long) kern_end);
-      err = grub_relocator_alloc_chunk_addr (relocator, &kern_chunk_src,
-                                            kern_start, kern_end - kern_start);
-      if (err)
-       return err;
+      {
+       grub_relocator_chunk_t ch;
+
+       err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start,
+                                              kern_end - kern_start);
+       if (err)
+         return err;
+       kern_chunk_src = get_virtual_current_address (ch);
+      }
 
       return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
     }
@@ -1682,10 +1721,15 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
   if ((!file) || (!file->size))
     goto fail;
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &src, kern_end, 
-                                        file->size);
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, 
+                                          file->size);
+    if (err)
+      goto fail;
+    src = get_virtual_current_address (ch);
+  }
+
 
   grub_file_read (file, src, file->size);
   if (grub_errno)
@@ -1728,10 +1772,15 @@ grub_netbsd_module_load (char *filename, grub_uint32_t type)
   if ((!file) || (!file->size))
     goto fail;
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &src, kern_end, 
-                                        file->size);
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, 
+                                          file->size);
+    if (err)
+      goto fail;
+
+    src = get_virtual_current_address (ch);
+  }
 
   grub_file_read (file, src, file->size);
   if (grub_errno)
index 7346337043b954feaa57bbd98f2bb9fb7e4896a8..85f4c6236e3c61d45e86fc1c56c1693b231f7fdb 100644 (file)
@@ -103,10 +103,14 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator,
       chunk_size += s->sh_size;
     }
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &chunk_src,
-                                        module, chunk_size);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          module, chunk_size);
+    if (err)
+      return err;
+    chunk_src = get_virtual_current_address (ch);
+  }
 
   for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
                                                + e.e_shnum * e.e_shentsize);
@@ -191,10 +195,16 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
        chunk_size = s->sh_addr + s->sh_size;
     }
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &chunk_src,
-                                        module, chunk_size);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          module, chunk_size);
+    if (err)
+      return err;
+
+    chunk_src = get_virtual_current_address (ch);
+  }
 
   for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
                                                + e.e_shnum * e.e_shentsize);
@@ -300,10 +310,15 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator,
     + 2 * sizeof (grub_freebsd_addr_t);
 
   symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
-  err = grub_relocator_alloc_chunk_addr (relocator, &sym_chunk,
-                                        symtarget, chunk_size);
-  if (err)
-    return err;
+
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          symtarget, chunk_size);
+    if (err)
+      return err;
+    sym_chunk = get_virtual_current_address (ch);
+  }
 
   symstart = symtarget;
   symend = symstart + chunk_size;
@@ -413,10 +428,14 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
     + sizeof (e) + e.e_shnum * e.e_shentsize;
 
   symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
-  err = grub_relocator_alloc_chunk_addr (relocator, &sym_chunk,
-                                        symtarget, chunk_size);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          symtarget, chunk_size);
+    if (err)
+      return err;
+    sym_chunk = get_virtual_current_address (ch);
+  }
 
   symtab.nsyms = 1;
   symtab.ssyms = symtarget;
index ef1b8309e9a950f8cc94a2ca19f415a1ad0df222..e05225f2558745c5cdcdbc7e3983ffb6e3a3ed77 100644 (file)
@@ -412,20 +412,28 @@ allocate_pages (grub_size_t prot_size)
       goto fail;
     }
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &real_mode_mem,
-                                        real_mode_target,
-                                        (real_size + mmap_size 
-                                         + efi_mmap_size));
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          real_mode_target,
+                                          (real_size + mmap_size 
+                                           + efi_mmap_size));
+    if (err)
+      goto fail;
+    real_mode_mem = get_virtual_current_address (ch);
+  }
   efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
 
   prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;
 
-  err = grub_relocator_alloc_chunk_addr (relocator, &prot_mode_mem,
-                                        prot_mode_target, prot_size);
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          prot_mode_target, prot_size);
+    if (err)
+      goto fail;
+    prot_mode_mem = get_virtual_current_address (ch);
+  }
 
   grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
                 "prot_mode_mem = %lx, prot_mode_pages = %x\n",
@@ -1111,12 +1119,16 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
       goto fail;
     }
 
-  err = grub_relocator_alloc_chunk_align (relocator, &initrd_mem,
-                                         &initrd_mem_target,
-                                         addr_min, addr, size, 0x1000,
-                                         GRUB_RELOCATOR_PREFERENCE_HIGH);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_align (relocator, &ch,
+                                           addr_min, addr, size, 0x1000,
+                                           GRUB_RELOCATOR_PREFERENCE_HIGH);
+    if (err)
+      return err;
+    initrd_mem = get_virtual_current_address (ch);
+    initrd_mem_target = get_physical_target_address (ch);
+  }
 
   if (grub_file_read (file, initrd_mem, size) != size)
     {
index 2f32c3f4e995d9e1aeb50cd6c3f21748defeee46..ea1385be765b2a1d54acab629142527c3450d376 100644 (file)
@@ -108,6 +108,7 @@ grub_multiboot_load (grub_file_t file)
                       header->load_end_addr - header->load_addr);
       grub_size_t code_size;
       void *source;
+      grub_relocator_chunk_t ch;
 
       if (header->bss_end_addr)
        code_size = (header->bss_end_addr - header->load_addr);
@@ -115,7 +116,7 @@ grub_multiboot_load (grub_file_t file)
        code_size = load_size;
 
       err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
-                                            &source, header->load_addr,
+                                            &ch, header->load_addr,
                                             code_size);
       if (err)
        {
@@ -123,6 +124,7 @@ grub_multiboot_load (grub_file_t file)
          grub_free (buffer);
          return err;
        }
+      source = get_virtual_current_address (ch);
 
       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
        {
@@ -322,16 +324,18 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
 
   grub_err_t err;
   grub_size_t bufsize;
+  grub_relocator_chunk_t ch;
 
   bufsize = grub_multiboot_get_mbi_size ();
 
-  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, 
-                                         (void **) &ptrorig, &ptrdest,
+  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
                                          0, 0xffffffff - bufsize,
                                          bufsize, 4,
                                          GRUB_RELOCATOR_PREFERENCE_NONE);
   if (err)
     return err;
+  ptrorig = get_virtual_current_address (ch);
+  ptrdest = (grub_addr_t) get_virtual_current_address (ch);
 
   *target = ptrdest;
 
index 176220a2b41fe5366e37ea825959b576f3b21eff..82640d77df45ca214590bae669df664387b6c632 100644 (file)
@@ -255,12 +255,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
          }
       }
 
-  err = grub_relocator_alloc_chunk_addr (relocator, (void **)
-                                        &grub_linux_real_chunk,
-                                        grub_linux_real_target,
-                                        GRUB_LINUX_SETUP_MOVE_SIZE);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          grub_linux_real_target,
+                                          GRUB_LINUX_SETUP_MOVE_SIZE);
+    if (err)
+      return err;
+    grub_linux_real_chunk = get_virtual_current_address (ch);
+  }
 
   /* Put the real mode code at the temporary address.  */
   grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh));
@@ -301,12 +304,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
     grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
   else
     grub_linux_prot_target = GRUB_LINUX_ZIMAGE_ADDR;
-  err = grub_relocator_alloc_chunk_addr (relocator,
-                                        (void **) &grub_linux_prot_chunk,
-                                        grub_linux_prot_target,
-                                        grub_linux16_prot_size);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+                                          grub_linux_prot_target,
+                                          grub_linux16_prot_size);
+    if (err)
+      return err;
+    grub_linux_prot_chunk = get_virtual_current_address (ch);
+  }
 
   len = grub_linux16_prot_size;
   if (grub_file_read (file, grub_linux_prot_chunk, grub_linux16_prot_size)
@@ -398,13 +404,17 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 
   size = grub_file_size (file);
 
-  err = grub_relocator_alloc_chunk_align (relocator, (void **) &initrd_chunk,
-                                         &initrd_addr,
-                                         addr_min, addr_max - size,
-                                         size, 0x1000,
-                                         GRUB_RELOCATOR_PREFERENCE_HIGH);
-  if (err)
-    return err;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_align (relocator, &ch,
+                                           addr_min, addr_max - size,
+                                           size, 0x1000,
+                                           GRUB_RELOCATOR_PREFERENCE_HIGH);
+    if (err)
+      return err;
+    initrd_chunk = get_virtual_current_address (ch);
+    initrd_addr = get_physical_target_address (ch);
+  }
 
   if (grub_file_read (file, initrd_chunk, size) != size)
     {
index 1368694fbeeb0b4a6763151f45027dab34f2d72c..0c33a068049de230be23710820b81804bb8029d4 100644 (file)
@@ -90,10 +90,14 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
   if (! file)
     goto fail;
 
-  err = grub_relocator_alloc_chunk_addr (rel, &bs, 0x7C00,
-                                        GRUB_DISK_SECTOR_SIZE);
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
+                                          GRUB_DISK_SECTOR_SIZE);
+    if (err)
+      goto fail;
+    bs = get_virtual_current_address (ch);
+  }
 
   edx = grub_get_root_biosnumber ();
   dev = grub_device_open (0);
@@ -112,10 +116,14 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
     grub_device_close (dev);
 
   ntldrsize = grub_file_size (file);
-  err = grub_relocator_alloc_chunk_addr (rel, &ntldr, GRUB_NTLDR_SEGMENT << 4,
-                                        ntldrsize);
-  if (err)
-    goto fail;
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
+                                          ntldrsize);
+    if (err)
+      goto fail;
+    ntldr = get_virtual_current_address (ch);
+  }
 
   if (grub_file_read (file, ntldr, ntldrsize)
       != (grub_ssize_t) ntldrsize)
index a3ca6266f5c913a0175f1329894e47a6d3469000..6c6afcee9a5ad8ce10827e2121d45ee5f2c37462 100644 (file)
@@ -284,16 +284,20 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
     return grub_errno;
 
   size = grub_file_size (file);
-  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &module, 
-                                         &target,
-                                         0, (0xffffffff - size) + 1,
-                                         size, MULTIBOOT_MOD_ALIGN,
-                                         GRUB_RELOCATOR_PREFERENCE_NONE);
-  if (err)
-    {
-      grub_file_close (file);
-      return err;
-    }
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
+                                           0, (0xffffffff - size) + 1,
+                                           size, MULTIBOOT_MOD_ALIGN,
+                                           GRUB_RELOCATOR_PREFERENCE_NONE);
+    if (err)
+      {
+       grub_file_close (file);
+       return err;
+      }
+    module = get_virtual_current_address (ch);
+    target = (grub_addr_t) get_virtual_current_address (ch);
+  }
 
   err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
   if (err)
index 561c7572cfbfe41ea620657ac592f10ea573fcd5..880e93ce50a5b6e657395c1a82cce8e10f48dcbf 100644 (file)
@@ -92,14 +92,18 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
          grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
                        i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
 
-         err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
-                                                &source, phdr(i)->p_paddr,
-                                                phdr(i)->p_memsz);
-         if (err)
-           {
-             grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
-             return err;
-           }
+         {
+           grub_relocator_chunk_t ch;
+           err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
+                                                  &ch, phdr(i)->p_paddr,
+                                                  phdr(i)->p_memsz);
+           if (err)
+             {
+               grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
+               return err;
+             }
+           source = get_virtual_current_address (ch);
+         }
 
          if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
              == (grub_off_t) -1)
@@ -163,18 +167,22 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
          if (sh->sh_size == 0)
            continue;
 
-         err 
-           = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
-                                               &src, &target, 0,
-                                               (0xffffffff - sh->sh_size) + 1,
-                                               sh->sh_size,
-                                               sh->sh_addralign,
-                                               GRUB_RELOCATOR_PREFERENCE_NONE);
-         if (err)
-           {
-             grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
-             return err;
-           }
+         {
+           grub_relocator_chunk_t ch;
+           err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
+                                                   &ch, 0,
+                                                   (0xffffffff - sh->sh_size)
+                                                   + 1, sh->sh_size,
+                                                   sh->sh_addralign,
+                                                   GRUB_RELOCATOR_PREFERENCE_NONE);
+           if (err)
+             {
+               grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
+               return err;
+             }
+           src = get_virtual_current_address (ch);
+           target = get_physical_target_address (ch);
+         }
 
          if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
            return grub_error (GRUB_ERR_BAD_OS,
index c5929f10f9647ee2ee5e40cfc7dda7459f2fa18a..5f4a5280035d9fa096869992ff24872a2a84d6c1 100644 (file)
@@ -191,6 +191,7 @@ grub_multiboot_load (grub_file_t file)
                       addr_tag->load_end_addr - addr_tag->load_addr);
       grub_size_t code_size;
       void *source;
+      grub_relocator_chunk_t ch;
 
       if (addr_tag->bss_end_addr)
        code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
@@ -198,7 +199,7 @@ grub_multiboot_load (grub_file_t file)
        code_size = load_size;
 
       err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, 
-                                            &source, addr_tag->load_addr,
+                                            &ch, addr_tag->load_addr,
                                             code_size);
       if (err)
        {
@@ -206,6 +207,7 @@ grub_multiboot_load (grub_file_t file)
          grub_free (buffer);
          return err;
        }
+      source = get_virtual_current_address (ch);
 
       if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
        {
@@ -460,19 +462,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
   grub_uint8_t *mbistart;
   grub_err_t err;
   grub_size_t bufsize;
-  grub_addr_t ptrdest;
+  grub_relocator_chunk_t ch;
 
   bufsize = grub_multiboot_get_mbi_size ();
 
-  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, 
-                                         (void **) &ptrorig, &ptrdest,
+  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
                                          0, 0xffffffff - bufsize,
                                          bufsize, 4,
                                          GRUB_RELOCATOR_PREFERENCE_NONE);
   if (err)
     return err;
 
-  *target = ptrdest;
+  ptrorig = get_virtual_current_address (ch);
+  *target = get_physical_target_address (ch);
 
   mbistart = ptrorig;
   ptrorig += 2 * sizeof (grub_uint32_t);
index f1d372b73331d40e604675ec3b2ce5e3bcf9ec73..17f8500189cecec0cde42c199a4daac0a06b808d 100644 (file)
@@ -51,13 +51,15 @@ grub_err_t
 grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
 {
   grub_err_t err;
+  grub_relocator_chunk_t ch;
   
-  err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, src,
+  err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
                                         grub_xnu_heap_target_start
                                         + grub_xnu_heap_size, size);
   if (err)
     return err;
 
+  *src = get_virtual_current_address (ch);
   *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
   grub_xnu_heap_size += size;
   grub_dprintf ("xnu", "val=%p\n", *src);
index 2d47df601c3d829322ee2e12e63771210e3a04e2..6aebc1f34b17c983fbf4dc4c9caaa9ec0a6fcf54 100644 (file)
@@ -103,25 +103,33 @@ grub_xnu_resume (char *imagename)
       return grub_errno;
     }
 
-  err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &code,
-                                        codedest, codesize + GRUB_XNU_PAGESIZE);
-  if (err)
-    {
-      grub_file_close (file);
-      return err;
-    }
-
-  err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &image,
-                                         &target_image, 0,
-                                         (0xffffffff - hibhead.image_size) + 1,
-                                         hibhead.image_size,
-                                         GRUB_XNU_PAGESIZE,
-                                         GRUB_RELOCATOR_PREFERENCE_NONE);
-  if (err)
-    {
-      grub_file_close (file);
-      return err;
-    }
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, codedest,
+                                          codesize + GRUB_XNU_PAGESIZE);
+    if (err)
+      {
+       grub_file_close (file);
+       return err;
+      }
+    code = get_virtual_current_address (ch);
+  }
+
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
+                                           (0xffffffff - hibhead.image_size) + 1,
+                                           hibhead.image_size,
+                                           GRUB_XNU_PAGESIZE,
+                                           GRUB_RELOCATOR_PREFERENCE_NONE);
+    if (err)
+      {
+       grub_file_close (file);
+       return err;
+      }
+    image = get_virtual_current_address (ch);
+    target_image = get_physical_target_address (ch);
+  }
 
   /* Read code part. */
   if (grub_file_seek (file, total_header_size) == (grub_off_t) -1