Module Name:    src
Committed By:   gsutre
Date:           Tue Jan 11 12:24:38 UTC 2011

Modified Files:
        src/sys/arch/i386/i386: multiboot.c

Log Message:
As said in the comment (lines 327-336), we must make sure that
we don't overwrite valid data when moving the symbol and string
tables.

Assume for instance that the boot-loader left us with:

  +--------------+   +--------+     +--------------+
  | string table |   | kernel |     | symbol table |
  +--------------+   +--------+     +--------------+

The new addresses computed by lines 338-359 (here, it's really
lines 344-345) will move the tables so that they end up as:

                     +--------+--------------+--------------+
                     | kernel | symbol table | string table |
                     +--------+--------------+--------------+

The current version (rev. 1.20) will, however, first copy the
string table and then the symbol table.  But the copy of the
string table will overwrite the symbol table (see the pictures).

The old code (rev. 1.19) uses the right order of table copy to
make sure that we don't overwrite one table when moving the
other.  Here, we simply restore this behavior.  This makes
multibooting from GRUB2 work again (for MONOLITHIC).

ok jmcneill@


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/i386/i386/multiboot.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/i386/multiboot.c
diff -u src/sys/arch/i386/i386/multiboot.c:1.20 src/sys/arch/i386/i386/multiboot.c:1.21
--- src/sys/arch/i386/i386/multiboot.c:1.20	Sat Jul 24 00:45:55 2010
+++ src/sys/arch/i386/i386/multiboot.c	Tue Jan 11 12:24:37 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: multiboot.c,v 1.20 2010/07/24 00:45:55 jym Exp $	*/
+/*	$NetBSD: multiboot.c,v 1.21 2011/01/11 12:24:37 gsutre Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.20 2010/07/24 00:45:55 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.21 2011/01/11 12:24:37 gsutre Exp $");
 
 #include "opt_multiboot.h"
 
@@ -339,28 +339,35 @@
 	    (void *)strtabp < RELOC(void *, &end)) {
 		symstart = RELOC(Elf32_Addr, &end);
 		strstart = symstart + symsize;
+		memcpy((void *)symstart, (void *)symaddr, symsize);
+		memcpy((void *)strstart, (void *)straddr, strsize);
         } else if ((void *)symtabp > RELOC(void *, &end) &&
 	           (void *)strtabp < RELOC(void *, &end)) {
 		symstart = RELOC(Elf32_Addr, &end);
 		strstart = symstart + symsize;
+		memcpy((void *)symstart, (void *)symaddr, symsize);
+		memcpy((void *)strstart, (void *)straddr, strsize);
         } else if ((void *)symtabp < RELOC(void *, &end) &&
 	           (void *)strtabp > RELOC(void *, &end)) {
 		strstart = RELOC(Elf32_Addr, &end);
 		symstart = strstart + strsize;
+		memcpy((void *)strstart, (void *)straddr, strsize);
+		memcpy((void *)symstart, (void *)symaddr, symsize);
 	} else {
 		/* symtabp and strtabp are both over end */
 		if (symtabp < strtabp) {
 			symstart = RELOC(Elf32_Addr, &end);
 			strstart = symstart + symsize;
+			memcpy((void *)symstart, (void *)symaddr, symsize);
+			memcpy((void *)strstart, (void *)straddr, strsize);
 		} else {
 			strstart = RELOC(Elf32_Addr, &end);
 			symstart = strstart + strsize;
+			memcpy((void *)strstart, (void *)straddr, strsize);
+			memcpy((void *)symstart, (void *)symaddr, symsize);
 		}
 	}
 
-	memcpy((void *)strstart, (void *)straddr, strsize);
-	memcpy((void *)symstart, (void *)symaddr, symsize);
-
 	*RELOC(int *, &esym) =
 	    (int)(symstart + symsize + strsize + KERNBASE);
 

Reply via email to