]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c
authorVladimir Serbinenko <phcoder@gmail.com>
Sun, 8 Dec 2013 17:07:41 +0000 (18:07 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sun, 8 Dec 2013 17:08:23 +0000 (18:08 +0100)
and implement windows variant.

ChangeLog
grub-core/Makefile.core.def
grub-core/kern/dl.c
grub-core/osdep/dl.c [new file with mode: 0644]
grub-core/osdep/unix/dl.c [new file with mode: 0644]
grub-core/osdep/windows/dl.c [new file with mode: 0644]
include/grub/dl.h

index 07f8dfb96042638060b12547fd886533cd10c323..6f90aada0e4275e9a6789c15b052dd03a204eb9b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-08  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c
+       and implement windows variant.
+
 2013-12-08  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Fix mips-emu compilation.
index 57abb491004c5fa3890914f3802e829e32df95f2..0a4eba56bebc0ae111eb5b8205bb61ca31b27172 100644 (file)
@@ -282,6 +282,9 @@ kernel = {
   emu = osdep/emuconsole.c;
   extra_dist = osdep/unix/emuconsole.c;
   extra_dist = osdep/windows/emuconsole.c;
+  emu = osdep/dl.c;
+  extra_dist = osdep/unix/dl.c;
+  extra_dist = osdep/windows/dl.c;
   emu = osdep/sleep.c;
   emu = osdep/init.c;
   emu = osdep/emunet.c;
index f01fcfd4f8156983d5a8f48b0563c47a0b47cec2..90589f75b3aa37de900fb4cae04b3217ed58a3ea 100644 (file)
 #define GRUB_MODULES_MACHINE_READONLY
 #endif
 
-#ifdef GRUB_MACHINE_EMU
-#include <sys/mman.h>
-#endif
-
 \f
 
 #pragma GCC diagnostic ignored "-Wcast-align"
@@ -258,21 +254,15 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
 #endif
 
 #ifdef GRUB_MACHINE_EMU
-  if (talign < 8192 * 16)
-    talign = 8192 * 16;
-  tsize = ALIGN_UP (tsize, 8192 * 16);
-#endif
-
+  mod->base = grub_osdep_dl_memalign (talign, tsize);
+#else
   mod->base = grub_memalign (talign, tsize);
+#endif
   if (!mod->base)
     return grub_errno;
   mod->sz = tsize;
   ptr = mod->base;
 
-#ifdef GRUB_MACHINE_EMU
-  mprotect (mod->base, tsize, PROT_READ | PROT_WRITE | PROT_EXEC);
-#endif
-
   for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
        i < e->e_shnum;
        i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
@@ -782,7 +772,11 @@ grub_dl_unload (grub_dl_t mod)
       grub_free (dep);
     }
 
+#ifdef GRUB_MACHINE_EMU
+  grub_dl_osdep_dl_free (mod->base);
+#else
   grub_free (mod->base);
+#endif
   grub_free (mod->name);
 #ifdef GRUB_MODULES_MACHINE_READONLY
   grub_free (mod->symtab);
diff --git a/grub-core/osdep/dl.c b/grub-core/osdep/dl.c
new file mode 100644 (file)
index 0000000..c511747
--- /dev/null
@@ -0,0 +1,5 @@
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+#include "windows/dl.c"
+#else
+#include "unix/dl.c"
+#endif
diff --git a/grub-core/osdep/unix/dl.c b/grub-core/osdep/unix/dl.c
new file mode 100644 (file)
index 0000000..562b101
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/>.
+ */
+
+#include <config.h>
+#include <config-util.h>
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <string.h>
+
+void *
+grub_osdep_dl_memalign (grub_size_t align, grub_size_t size)
+{
+  void *ret;
+  if (align < 8192 * 16)
+    align = 8192 * 16;
+  size = ALIGN_UP (size, 8192 * 16);
+
+#if defined(HAVE_POSIX_MEMALIGN)
+  if (posix_memalign (&ret, align, size) != 0)
+    ret = 0;
+#elif defined(HAVE_MEMALIGN)
+  ret = memalign (align, size);
+#else
+#error "Complete this"
+#endif
+
+  if (!ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      return NULL;
+    }
+
+  mprotect (ret, size, PROT_READ | PROT_WRITE | PROT_EXEC);
+  return ret;
+}
+
+void
+grub_dl_osdep_dl_free (void *ptr)
+{
+  if (ptr)
+    free (ptr);
+}
diff --git a/grub-core/osdep/windows/dl.c b/grub-core/osdep/windows/dl.c
new file mode 100644 (file)
index 0000000..b18a4a0
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/>.
+ */
+
+#include <config.h>
+#include <config-util.h>
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+
+void *
+grub_osdep_dl_memalign (grub_size_t align, grub_size_t size)
+{
+  void *ret;
+  if (align > 4096)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("too large alignment"));
+      return NULL;
+    }
+
+  size = ALIGN_UP (size, 4096);
+
+  ret = VirtualAlloc (NULL, size, MEM_COMMIT | MEM_RESERVE,
+                     PAGE_EXECUTE_READWRITE);
+
+  if (!ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      return NULL;
+    }
+
+  return ret;
+}
+
+void
+grub_dl_osdep_dl_free (void *ptr)
+{
+  if (!ptr)
+    return;
+  VirtualFree (ptr, 0,  MEM_RELEASE);
+}
index 6c758c01a92491ba931c5996d1df29993597bac9..58b636f16ca8d4cc8dbc10cd451de641b1f075cd 100644 (file)
@@ -210,6 +210,13 @@ extern grub_dl_t EXPORT_VAR(grub_dl_head);
 
 #define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head))
 
+#ifdef GRUB_MACHINE_EMU
+void *
+grub_osdep_dl_memalign (grub_size_t align, grub_size_t size);
+void
+grub_dl_osdep_dl_free (void *ptr);
+#endif
+
 static inline void
 grub_dl_init (grub_dl_t mod)
 {