All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Boettcher <alexander.boettcher@genode-labs.com>
To: grub-devel@gnu.org
Subject: [PATCH] mbi: use per segment a separate relocator chunk
Date: Mon, 14 May 2018 21:02:00 +0200	[thread overview]
Message-ID: <c87ae20e-de95-160b-006e-1eb449954a36@genode-labs.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 216 bytes --]


-- 
Alexander Boettcher
Genode Labs

http://www.genode-labs.com - http://www.genode.org

Genode Labs GmbH - Amtsgericht Dresden - HRB 28424 - Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth

[-- Attachment #2: 0001-mbi-use-per-segment-a-separate-relocator-chunk.patch --]
[-- Type: text/x-patch, Size: 4873 bytes --]

From 8a0296d040a42950cd64e733f7997203975bc184 Mon Sep 17 00:00:00 2001
From: Alexander Boettcher <alexander.boettcher@genode-labs.com>
Date: Fri, 13 Apr 2018 23:37:01 +0200
Subject: [PATCH] mbi: use per segment a separate relocator chunk

if elf is non relocatable.

If the segments are not dense packed, the original code set up a huge
relocator chunk comprising all segments.

During the final relocation in grub_relocator_prepare_relocs, the chunk
is moved to its desired place and overrides memory which are actually not
covered/touched by the specified segments.

The overriden memory may contain device memory (vga text mode e.g.), which
leads to strange boot behaviour.

Signed-off-by: Alexander Boettcher <alexander.boettcher@genode-labs.com>
---
 grub-core/loader/multiboot_elfxx.c | 57 +++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
index 67daf59..539c94a 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -57,9 +57,9 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
   char *phdr_base;
   grub_err_t err;
   grub_relocator_chunk_t ch;
-  grub_uint32_t load_offset, load_size;
+  grub_uint32_t load_offset = 0, load_size;
   int i;
-  void *source;
+  void *source = NULL;
 
   if (ehdr->e_ident[EI_MAG0] != ELFMAG0
       || ehdr->e_ident[EI_MAG1] != ELFMAG1
@@ -83,6 +83,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
 #define phdr(i)			((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
 
   mld->link_base_addr = ~0;
+  mld->load_base_addr = ~0;
 
   /* Calculate lowest and highest load address.  */
   for (i = 0; i < ehdr->e_phnum; i++)
@@ -97,10 +98,14 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
     return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
 #endif
 
-  load_size = highest_load - mld->link_base_addr;
+  grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
+		"relocatable=%d\n", mld->link_base_addr,
+		mld->load_base_addr, mld->relocatable);
 
   if (mld->relocatable)
     {
+      load_size = highest_load - mld->link_base_addr;
+
       if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
 	return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
 
@@ -108,27 +113,19 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
 					      mld->min_addr, mld->max_addr - load_size,
 					      load_size, mld->align ? mld->align : 1,
 					      mld->preference, mld->avoid_efi_boot_services);
-    }
-  else
-    err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch,
-					   mld->link_base_addr, load_size);
 
-  if (err)
-    {
-      grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
-      return err;
-    }
-
-  mld->load_base_addr = get_physical_target_address (ch);
-  source = get_virtual_current_address (ch);
+      if (err)
+        {
+          grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
+          return err;
+        }
 
-  grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
-		"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
-		mld->load_base_addr, load_size, mld->relocatable);
+      mld->load_base_addr = get_physical_target_address (ch);
+      source = get_virtual_current_address (ch);
 
-  if (mld->relocatable)
-    grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
-		  (long) mld->align, mld->preference, mld->avoid_efi_boot_services);
+      grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
+		     (long) mld->align, mld->preference, mld->avoid_efi_boot_services);
+    }
 
   /* Load every loadable segment in memory.  */
   for (i = 0; i < ehdr->e_phnum; i++)
@@ -139,7 +136,23 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
 	  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);
 
-	  load_offset = phdr(i)->p_paddr - mld->link_base_addr;
+	  if (mld->relocatable)
+	    load_offset = phdr(i)->p_paddr - mld->link_base_addr;
+	  else
+	    {
+	      err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch,
+	                                             phdr(i)->p_paddr, phdr(i)->p_memsz);
+
+	      if (err)
+		{
+		  grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
+		  return err;
+		}
+
+	      mld->load_base_addr = grub_min (mld->load_base_addr, get_physical_target_address (ch));
+
+	      source = get_virtual_current_address (ch);
+	    }
 
 	  if (phdr(i)->p_filesz != 0)
 	    {
-- 
2.7.4


             reply	other threads:[~2018-05-14 19:17 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-14 19:02 Alexander Boettcher [this message]
2018-05-15 13:42 ` [PATCH] mbi: use per segment a separate relocator chunk Daniel Kiper
2018-05-15 19:10   ` Alexander Boettcher
2018-05-15 19:18     ` Alexander Boettcher
2018-05-16 10:22       ` Daniel Kiper
2018-06-05 19:59   ` Alexander Boettcher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c87ae20e-de95-160b-006e-1eb449954a36@genode-labs.com \
    --to=alexander.boettcher@genode-labs.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.