]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
support for registering functions from modules (not tested yet)
authorphcoder <phcoder@debian>
Sun, 2 Jan 2011 13:58:57 +0000 (14:58 +0100)
committerphcoder <phcoder@debian>
Sun, 2 Jan 2011 13:58:57 +0000 (14:58 +0100)
grub-core/kern/dl.c
grub-core/kern/emu/full.c
grub-core/kern/ia64/dl.c
include/grub/dl.h

index 2f2493fca7889564fa6048364c4cca76c5064a56..9dfff52870da2e49c09c65e198d14739c2e896f3 100644 (file)
@@ -360,9 +360,22 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
          sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
                                                                sym->st_shndx);
          if (bind != STB_LOCAL)
-           if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
-             return grub_errno;
-
+           {
+#ifdef __ia64__
+             /* FIXME: free descriptor once it's not used anymore. */
+             char **desc;
+             desc = grub_malloc (2 * sizeof (char *));
+             if (!desc)
+               return grub_errno;
+             desc[0] = (void *) sym->st_value;
+             desc[1] = mod->gp;
+             if (grub_dl_register_symbol (name, (void *) desc, mod))
+               return grub_errno;
+#else
+             if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
+               return grub_errno;
+#endif
+           }
          if (grub_strcmp (name, "grub_mod_init") == 0)
            mod->init = sym->st_value;
          else if (grub_strcmp (name, "grub_mod_fini") == 0)
@@ -552,6 +565,7 @@ grub_dl_load_core (void *addr, grub_size_t size)
   if (grub_dl_resolve_name (mod, e)
       || grub_dl_resolve_dependencies (mod, e)
       || grub_dl_load_segments (mod, e)
+      || grub_arch_dl_allocate_gp (mod, e)
       || grub_dl_resolve_symbols (mod, e)
       || grub_arch_dl_relocate_symbols (mod, e))
     {
index 0396d0ab4e88ef456a006cea21cc0b2deaddf5be..67a12530106b038b0ecee6c60a264537055e8cdc 100644 (file)
@@ -56,4 +56,12 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)),
 {
   return ~(grub_size_t)0;
 }
+
+grub_err_t
+grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)),
+                         const void *ehdr __attribute__ ((unused)))
+{
+  return GRUB_ERR_BAD_MODULE;
+}
+
 #endif
index 24fa01b908c666681740966f9ce3078d4e2f4bc2..1fbe185b40afe1d4167faf9b9d4ed24295c679f1 100644 (file)
@@ -154,16 +154,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec)
   return cnt * sizeof (struct ia64_trampoline);
 }
 
-/* Relocate symbols.  */
 grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr)
 {
-  Elf_Ehdr *e = ehdr;
-  Elf_Shdr *s;
-  Elf_Word entsize;
-  unsigned i;
-  grub_uint64_t *gp, *gpptr;
   grub_size_t gp_size = 0;
+  const Elf_Ehdr *e = ehdr;
+  const Elf_Shdr *s;
+  unsigned i;
 
   for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
        i < e->e_shnum;
@@ -199,10 +196,23 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
   if (gp_size > MASK19)
     return grub_error (GRUB_ERR_OUT_OF_RANGE, "gp too big");
 
-  gpptr = gp = grub_malloc (gp_size);
-  if (!gp)
+  mod->gp = grub_malloc (gp_size);
+  if (!mod->gp)
     return grub_errno;
-  mod->gp = (char *) gp;
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+  grub_uint64_t *gp, *gpptr;
+
+  gp = gpptr = (grub_uint64_t *) mod->gp;
 
   /* Find a symbol table.  */
   for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
index e04285280c7fb5158626c056e15efa107432d6d7..c43c30ca7e2d56ddc1a02812968b981a81fe8a57 100644 (file)
@@ -124,6 +124,8 @@ void grub_arch_dl_init_linker (void);
 
 #ifdef __ia64__
 grub_size_t grub_arch_dl_get_tramp_size (const void *ehdr, unsigned sec);
+grub_err_t grub_arch_dl_allocate_gp (grub_dl_t mod, const void *ehdr);
+
 #define GRUB_ARCH_DL_TRAMP_ALIGN 16
 #else
 static inline grub_size_t
@@ -131,6 +133,13 @@ grub_arch_dl_get_tramp_size (const void *ehdr __attribute__ ((unused)), int sec
 {
   return 0;
 }
+static inline grub_err_t
+grub_arch_dl_allocate_gp (grub_dl_t mod __attribute__ ((unused)),
+                         const void *ehdr __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
 #define GRUB_ARCH_DL_TRAMP_ALIGN 1
 #endif