summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-03-11 05:14:32 +0000
committerMike Frysinger <vapier@gentoo.org>2005-03-11 05:14:32 +0000
commitcf335761aa94c7908c7801402107e6834307f617 (patch)
tree4677de6961025a6d04cc273356fff127601e7d7f /sys-boot/grub
parenttouchups (diff)
downloadgentoo-2-cf335761aa94c7908c7801402107e6834307f617.tar.gz
gentoo-2-cf335761aa94c7908c7801402107e6834307f617.tar.bz2
gentoo-2-cf335761aa94c7908c7801402107e6834307f617.zip
Add patches/fixes for a bunch of bugs ... basically lets fix i2o-raid support, NX segfaults on amd64, PIC build failures, and hardened objcopy funk. Thanks to Ryan Hill and everyone on #80693.
(Portage version: 2.0.51.19)
Diffstat (limited to 'sys-boot/grub')
-rw-r--r--sys-boot/grub/ChangeLog11
-rw-r--r--sys-boot/grub/files/digest-grub-0.96-r12
-rw-r--r--sys-boot/grub/files/grub-0.96-PIC.patch68
-rw-r--r--sys-boot/grub/files/grub-0.96-i2o-raid.patch61
-rw-r--r--sys-boot/grub/files/grub-0.96-nxstack.patch616
-rw-r--r--sys-boot/grub/grub-0.96-r1.ebuild155
6 files changed, 912 insertions, 1 deletions
diff --git a/sys-boot/grub/ChangeLog b/sys-boot/grub/ChangeLog
index 042c347416c6..30f02425205c 100644
--- a/sys-boot/grub/ChangeLog
+++ b/sys-boot/grub/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog for sys-boot/grub
# Copyright 2002-2005 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/ChangeLog,v 1.33 2005/03/05 20:28:13 azarah Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/ChangeLog,v 1.34 2005/03/11 05:14:32 vapier Exp $
+
+*grub-0.96-r1 (11 Mar 2005)
+
+ 11 Mar 2005; Mike Frysinger <vapier@gentoo.org>
+ +files/grub-0.96-PIC.patch, +files/grub-0.96-i2o-raid.patch,
+ +files/grub-0.96-nxstack.patch, +grub-0.96-r1.ebuild:
+ Add patches/fixes for a bunch of bugs ... basically lets fix i2o-raid
+ support, NX segfaults on amd64, PIC build failures, and hardened objcopy
+ funk. Thanks to Ryan Hill and everyone on #80693.
*grub-0.96 (05 Mar 2005)
diff --git a/sys-boot/grub/files/digest-grub-0.96-r1 b/sys-boot/grub/files/digest-grub-0.96-r1
new file mode 100644
index 000000000000..b43ad3d90a05
--- /dev/null
+++ b/sys-boot/grub/files/digest-grub-0.96-r1
@@ -0,0 +1,2 @@
+MD5 47c228c88f848873288ad1cd04cc93f0 grub-0.96.tar.gz 985761
+MD5 7d0c1f5a474a8877a6f38edc4599030a grub-0.95.20040823-splash.patch.bz2 40226
diff --git a/sys-boot/grub/files/grub-0.96-PIC.patch b/sys-boot/grub/files/grub-0.96-PIC.patch
new file mode 100644
index 000000000000..0f09ec7c756b
--- /dev/null
+++ b/sys-boot/grub/files/grub-0.96-PIC.patch
@@ -0,0 +1,68 @@
+--- grub-0.96/stage2/char_io.c.orig 2005-02-18 09:12:39.163407496 +0100
++++ grub-0.96/stage2/char_io.c 2005-02-18 09:13:11.431502000 +0100
+@@ -1202,34 +1202,59 @@
+ }
+ #endif /* ! STAGE1_5 */
+
++#ifdef GRUB_UTIL
++# ifdef __PIC__
++# if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL)
++ extern char start[];
++ extern char end[];
++# elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL)
++ extern char _start[];
++ extern char _end[];
++# endif
++# endif
++#endif
+ int
+ memcheck (int addr, int len)
+ {
+ #ifdef GRUB_UTIL
++# ifdef __PIC__
++# if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL)
++ if (start <= addr && end > addr + len)
++ return ! errnum;
++# elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL)
++ if (_start <= addr && _end > addr + len)
++ return ! errnum;
++# endif
++# else /* __PIC__ */
+ static int start_addr (void)
+ {
+ int ret;
+-# if defined(HAVE_START_SYMBOL)
++# if defined(HAVE_START_SYMBOL)
+ asm volatile ("movl $start, %0" : "=a" (ret));
+-# elif defined(HAVE_USCORE_START_SYMBOL)
++# elif defined(HAVE_USCORE_START_SYMBOL)
+ asm volatile ("movl $_start, %0" : "=a" (ret));
+-# endif
++# else
++ erk! /* function would return undefined data in this case - barf */
++# endif
+ return ret;
+ }
+
+ static int end_addr (void)
+ {
+ int ret;
+-# if defined(HAVE_END_SYMBOL)
++# if defined(HAVE_END_SYMBOL)
+ asm volatile ("movl $end, %0" : "=a" (ret));
+-# elif defined(HAVE_USCORE_END_SYMBOL)
++# elif defined(HAVE_USCORE_END_SYMBOL)
+ asm volatile ("movl $_end, %0" : "=a" (ret));
+-# endif
++# else
++ erk! /* function would return undefined data in this case - barf */
++# endif
+ return ret;
+ }
+
+ if (start_addr () <= addr && end_addr () > addr + len)
+ return ! errnum;
++# endif /* __PIC__ */
+ #endif /* GRUB_UTIL */
+
+ if ((addr < RAW_ADDR (0x1000))
diff --git a/sys-boot/grub/files/grub-0.96-i2o-raid.patch b/sys-boot/grub/files/grub-0.96-i2o-raid.patch
new file mode 100644
index 000000000000..5beec6f81198
--- /dev/null
+++ b/sys-boot/grub/files/grub-0.96-i2o-raid.patch
@@ -0,0 +1,61 @@
+diff -ru grub-0.96-orig/lib/device.c grub-0.96/lib/device.c
+--- grub-0.96-orig/lib/device.c 2005-02-16 22:33:09.669384408 -0600
++++ grub-0.96/lib/device.c 2005-02-17 00:47:05.127596672 -0600
+@@ -407,6 +407,12 @@
+ {
+ sprintf (name, "/dev/ataraid/d%c", unit + '0');
+ }
++
++static void
++get_i2o_disk_name (char *name, int unit)
++{
++ sprintf (name, "/dev/i2o/hd%c", unit + 'a');
++}
+ #endif
+
+ /* Check if DEVICE can be read. If an error occurs, return zero,
+@@ -798,6 +804,26 @@
+ }
+ }
+ }
++
++ /* I2O disks. */
++ for (i = 0; i < 8; i++)
++ {
++ char name[16];
++
++ get_i2o_disk_name (name, i);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++
+ #endif /* __linux__ */
+
+ /* OK, close the device map file if opened. */
+@@ -858,8 +884,15 @@
+ if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+ strcpy (dev + strlen(dev) - 5, "/part");
+ }
+- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
+-
++ sprintf (dev + strlen(dev), "%s%d",
++ /* Compaq smart and others */
++ (strncmp(dev, "/dev/ida/", 9) == 0 ||
++ strncmp(dev, "/dev/ataraid/", 13) == 0 ||
++ strncmp(dev, "/dev/cciss/", 11) == 0 ||
++ strncmp(dev, "/dev/rd/", 8) == 0 ||
++ strncmp(dev, "/dev/i2o/", 9) == 0) ? "p" : "",
++ ((partition >> 16) & 0xFF) + 1);
++
+ /* Open the partition. */
+ fd = open (dev, O_RDWR);
+ if (fd < 0)
diff --git a/sys-boot/grub/files/grub-0.96-nxstack.patch b/sys-boot/grub/files/grub-0.96-nxstack.patch
new file mode 100644
index 000000000000..5d305cefcd53
--- /dev/null
+++ b/sys-boot/grub/files/grub-0.96-nxstack.patch
@@ -0,0 +1,616 @@
+diff -ur grub-0.96-orig/grub/asmstub.c grub-0.96/grub/asmstub.c
+--- grub-0.96-orig/grub/asmstub.c 2004-03-12 11:01:49.000000000 -0600
++++ grub-0.96/grub/asmstub.c 2005-03-10 02:47:00.133431480 -0600
+@@ -42,6 +42,7 @@
+ #include <sys/time.h>
+ #include <termios.h>
+ #include <signal.h>
++#include <sys/mman.h>
+
+ #ifdef __linux__
+ # include <sys/ioctl.h> /* ioctl */
+@@ -79,7 +80,7 @@
+ struct apm_info apm_bios_info;
+
+ /* Emulation requirements. */
+-char *grub_scratch_mem = 0;
++void *grub_scratch_mem = 0;
+
+ struct geometry *disks = 0;
+
+@@ -103,14 +104,62 @@
+ static unsigned int serial_speed;
+ #endif /* SIMULATE_SLOWNESS_OF_SERIAL */
+
++/* This allocates page-aligned storage of the specified size, which must be
++ * a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE)
++ */
++#ifdef __linux__
++static void *
++grub_mmap_alloc(size_t len)
++{
++ int mmap_flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_EXECUTABLE;
++
++#ifdef MAP_32BIT
++ mmap_flags |= MAP_32BIT;
++#endif
++ /* Mark the simulated stack executable, as GCC uses stack trampolines
++ * to implement nested functions. */
++ return mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0);
++}
++#else /* !defined(__linux__) */
++static void *
++grub_mmap_alloc(size_t len)
++{
++ int fd = 0, offset = 0, ret = 0;
++ void *pa = MAP_FAILED;
++ char template[] = "/tmp/grub_mmap_alloc_XXXXXX";
++ errno_t e;
++
++ fd = mkstemp(template);
++ if (fd < 0)
++ return pa;
++
++ unlink(template);
++
++ ret = ftruncate(fd, len);
++ if (ret < 0)
++ return pa;
++
++ /* Mark the simulated stack executable, as GCC uses stack trampolines
++ * to implement nested functions. */
++ pa = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC,
++ MAP_PRIVATE|MAP_EXECUTABLE, fd, offset);
++
++ e = errno;
++ close(fd);
++ errno = e;
++ return pa;
++}
++#endif /* defined(__linux__) */
++
+ /* The main entry point into this mess. */
+ int
+ grub_stage2 (void)
+ {
+ /* These need to be static, because they survive our stack transitions. */
+ static int status = 0;
+- static char *realstack;
+- char *scratch, *simstack;
++ static void *realstack;
++ void *simstack_alloc_base, *simstack;
++ size_t simstack_size, page_size;
+ int i;
+
+ /* We need a nested function so that we get a clean stack frame,
+@@ -140,9 +189,35 @@
+ }
+
+ assert (grub_scratch_mem == 0);
+- scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
+- assert (scratch);
+- grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
++
++ /* Allocate enough pages for 0x100000 + EXTENDED_SIZE + 15, and
++ * make sure the memory is aligned to a multiple of the system's
++ * page size */
++ page_size = sysconf (_SC_PAGESIZE);
++ simstack_size = ( 0x100000 + EXTENDED_MEMSIZE + 15);
++ if (simstack_size % page_size)
++ {
++ /* If we're not on a page_size boundary, round up to the next one */
++ simstack_size &= ~(page_size-1);
++ simstack_size += page_size;
++ }
++
++ /* Add one for a PROT_NONE boundary page at each end. */
++ simstack_size += 2 * page_size;
++
++ simstack_alloc_base = grub_mmap_alloc(simstack_size);
++ assert (simstack_alloc_base != MAP_FAILED);
++
++ /* mark pages above and below our simstack area as innaccessable.
++ * If the implementation we're using doesn't support that, then the
++ * new protection modes are undefined. It's safe to just ignore
++ * them, though. It'd be nice if we knew that we'd get a SEGV for
++ * touching the area, but that's all. it'd be nice to have. */
++ mprotect (simstack_alloc_base, page_size, PROT_NONE);
++ mprotect ((void *)((unsigned long)simstack_alloc_base +
++ simstack_size - page_size), page_size, PROT_NONE);
++
++ grub_scratch_mem = (void *)((unsigned long)simstack_alloc_base + page_size);
+
+ /* FIXME: simulate the memory holes using mprot, if available. */
+
+@@ -215,7 +290,7 @@
+ device_map = 0;
+ free (disks);
+ disks = 0;
+- free (scratch);
++ munmap(simstack_alloc_base, simstack_size);
+ grub_scratch_mem = 0;
+
+ if (serial_device)
+Only in grub-0.96/stage2: .builtins.c.swp
+diff -ur grub-0.96-orig/stage2/builtins.c grub-0.96/stage2/builtins.c
+--- grub-0.96-orig/stage2/builtins.c 2005-03-10 02:28:24.704002000 -0600
++++ grub-0.96/stage2/builtins.c 2005-03-10 03:48:32.665081344 -0600
+@@ -131,61 +131,98 @@
+ }
+
+
++/* blocklist_read_helper nee disk_read_blocklist_func was a nested
++ * function, to which pointers were taken and exposed globally. Even
++ * in the GNU-C nested functions extension, they have local linkage,
++ * and aren't guaranteed to be accessable *at all* outside of their
++ * containing scope.
++ *
++ * Above and beyond all of that, the variables within blocklist_func_context
++ * are originally local variables, with local (not even static) linkage,
++ * from within blocklist_func. These were each referenced by
++ * disk_read_blocklist_func, which is only called from other functions
++ * through a globally scoped pointer.
++ *
++ * The documentation in GCC actually uses the words "all hell will break
++ * loose" to describe this scenario.
++ *
++ * Also, "start_sector" was also used uninitialized, but gcc doesn't warn
++ * about it (possibly because of the scoping madness?)
++ */
++
++static struct {
++ int start_sector;
++ int num_sectors;
++ int num_entries;
++ int last_length;
++} blocklist_func_context = {
++ .start_sector = 0,
++ .num_sectors = 0,
++ .num_entries = 0,
++ .last_length = 0
++};
++
++/* Collect contiguous blocks into one entry as many as possible,
++ and print the blocklist notation on the screen. */
++static void
++blocklist_read_helper (int sector, int offset, int length)
++{
++ int *start_sector = &blocklist_func_context.start_sector;
++ int *num_sectors = &blocklist_func_context.num_sectors;
++ int *num_entries = &blocklist_func_context.num_entries;
++ int *last_length = &blocklist_func_context.last_length;
++
++ if (*num_sectors > 0)
++ {
++ if (*start_sector + *num_sectors == sector
++ && offset == 0 && *last_length == SECTOR_SIZE)
++ {
++ *num_sectors++;
++ *last_length = length;
++ return;
++ }
++ else
++ {
++ if (*last_length == SECTOR_SIZE)
++ grub_printf ("%s%d+%d", *num_entries ? "," : "",
++ *start_sector - part_start, *num_sectors);
++ else if (*num_sectors > 1)
++ grub_printf ("%s%d+%d,%d[0-%d]", *num_entries ? "," : "",
++ *start_sector - part_start, *num_sectors-1,
++ *start_sector + *num_sectors-1 - part_start,
++ *last_length);
++ else
++ grub_printf ("%s%d[0-%d]", *num_entries ? "," : "",
++ *start_sector - part_start, *last_length);
++ *num_entries++;
++ *num_sectors = 0;
++ }
++ }
++
++ if (offset > 0)
++ {
++ grub_printf("%s%d[%d-%d]", *num_entries ? "," : "",
++ sector-part_start, offset, offset+length);
++ *num_entries++;
++ }
++ else
++ {
++ *start_sector = sector;
++ *num_sectors = 1;
++ *last_length = length;
++ }
++}
++
+ /* blocklist */
+ static int
+ blocklist_func (char *arg, int flags)
+ {
+ char *dummy = (char *) RAW_ADDR (0x100000);
+- int start_sector;
+- int num_sectors = 0;
+- int num_entries = 0;
+- int last_length = 0;
+-
+- /* Collect contiguous blocks into one entry as many as possible,
+- and print the blocklist notation on the screen. */
+- static void disk_read_blocklist_func (int sector, int offset, int length)
+- {
+- if (num_sectors > 0)
+- {
+- if (start_sector + num_sectors == sector
+- && offset == 0 && last_length == SECTOR_SIZE)
+- {
+- num_sectors++;
+- last_length = length;
+- return;
+- }
+- else
+- {
+- if (last_length == SECTOR_SIZE)
+- grub_printf ("%s%d+%d", num_entries ? "," : "",
+- start_sector - part_start, num_sectors);
+- else if (num_sectors > 1)
+- grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "",
+- start_sector - part_start, num_sectors-1,
+- start_sector + num_sectors-1 - part_start,
+- last_length);
+- else
+- grub_printf ("%s%d[0-%d]", num_entries ? "," : "",
+- start_sector - part_start, last_length);
+- num_entries++;
+- num_sectors = 0;
+- }
+- }
+-
+- if (offset > 0)
+- {
+- grub_printf("%s%d[%d-%d]", num_entries ? "," : "",
+- sector-part_start, offset, offset+length);
+- num_entries++;
+- }
+- else
+- {
+- start_sector = sector;
+- num_sectors = 1;
+- last_length = length;
+- }
+- }
+
++ int *start_sector = &blocklist_func_context.start_sector;
++ int *num_sectors = &blocklist_func_context.num_sectors;
++ int *num_entries = &blocklist_func_context.num_entries;
++
+ /* Open the file. */
+ if (! grub_open (arg))
+ return 1;
+@@ -204,15 +241,15 @@
+ grub_printf (")");
+
+ /* Read in the whole file to DUMMY. */
+- disk_read_hook = disk_read_blocklist_func;
++ disk_read_hook = blocklist_read_helper;
+ if (! grub_read (dummy, -1))
+ goto fail;
+
+ /* The last entry may not be printed yet. Don't check if it is a
+ * full sector, since it doesn't matter if we read too much. */
+- if (num_sectors > 0)
+- grub_printf ("%s%d+%d", num_entries ? "," : "",
+- start_sector - part_start, num_sectors);
++ if (*num_sectors > 0)
++ grub_printf ("%s%d+%d", *num_entries ? "," : "",
++ *start_sector - part_start, *num_sectors);
+
+ grub_printf ("\n");
+
+@@ -1868,6 +1905,77 @@
+
+
+ /* install */
++static struct {
++ int saved_sector;
++ int installaddr;
++ int installlist;
++ char *stage2_first_buffer;
++} install_func_context = {
++ .saved_sector = 0,
++ .installaddr = 0,
++ .installlist = 0,
++ .stage2_first_buffer = NULL,
++};
++
++/* Save the first sector of Stage2 in STAGE2_SECT. */
++/* Formerly disk_read_savesect_func with local scope inside install_func */
++static void
++install_savesect_helper(int sector, int offset, int length)
++{
++ if (debug)
++ printf ("[%d]", sector);
++
++ /* ReiserFS has files which sometimes contain data not aligned
++ on sector boundaries. Returning an error is better than
++ silently failing. */
++ if (offset != 0 || length != SECTOR_SIZE)
++ errnum = ERR_UNALIGNED;
++
++ install_func_context.saved_sector = sector;
++}
++
++/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and INSTALLSECT. */
++/* Formerly disk_read_blocklist_func with local scope inside install_func */
++static void
++install_blocklist_helper (int sector, int offset, int length)
++{
++ int *installaddr = &install_func_context.installaddr;
++ int *installlist = &install_func_context.installlist;
++ char **stage2_first_buffer = &install_func_context.stage2_first_buffer;
++ /* Was the last sector full? */
++ static int last_length = SECTOR_SIZE;
++
++ if (debug)
++ printf("[%d]", sector);
++
++ if (offset != 0 || last_length != SECTOR_SIZE)
++ {
++ /* We found a non-sector-aligned data block. */
++ errnum = ERR_UNALIGNED;
++ return;
++ }
++
++ last_length = length;
++
++ if (*((unsigned long *) (*installlist - 4))
++ + *((unsigned short *) *installlist) != sector
++ || *installlist == (int) *stage2_first_buffer + SECTOR_SIZE + 4)
++ {
++ *installlist -= 8;
++
++ if (*((unsigned long *) (*installlist - 8)))
++ errnum = ERR_WONT_FIT;
++ else
++ {
++ *((unsigned short *) (*installlist + 2)) = (*installaddr >> 4);
++ *((unsigned long *) (*installlist - 4)) = sector;
++ }
++ }
++
++ *((unsigned short *) *installlist) += 1;
++ *installaddr += 512;
++}
++
+ static int
+ install_func (char *arg, int flags)
+ {
+@@ -1875,8 +1983,12 @@
+ char *stage1_buffer = (char *) RAW_ADDR (0x100000);
+ char *stage2_buffer = stage1_buffer + SECTOR_SIZE;
+ char *old_sect = stage2_buffer + SECTOR_SIZE;
+- char *stage2_first_buffer = old_sect + SECTOR_SIZE;
+- char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE;
++ /* stage2_first_buffer used to be defined as:
++ * char *stage2_first_buffer = old_sect + SECTOR_SIZE; */
++ char **stage2_first_buffer = &install_func_context.stage2_first_buffer;
++ /* and stage2_second_buffer was:
++ * char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; */
++ char *stage2_second_buffer = old_sect + SECTOR_SIZE + SECTOR_SIZE;
+ /* XXX: Probably SECTOR_SIZE is reasonable. */
+ char *config_filename = stage2_second_buffer + SECTOR_SIZE;
+ char *dummy = config_filename + SECTOR_SIZE;
+@@ -1885,10 +1997,11 @@
+ int src_drive, src_partition, src_part_start;
+ int i;
+ struct geometry dest_geom, src_geom;
+- int saved_sector;
++ int *saved_sector = &install_func_context.saved_sector;
+ int stage2_first_sector, stage2_second_sector;
+ char *ptr;
+- int installaddr, installlist;
++ int *installaddr = &install_func_context.installaddr;
++ int *installlist = &install_func_context.installlist;
+ /* Point to the location of the name of a configuration file in Stage 2. */
+ char *config_file_location;
+ /* If FILE is a Stage 1.5? */
+@@ -1897,64 +2010,13 @@
+ int is_open = 0;
+ /* If LBA is forced? */
+ int is_force_lba = 0;
+- /* Was the last sector full? */
+- int last_length = SECTOR_SIZE;
+-
++
++ *stage2_first_buffer = old_sect + SECTOR_SIZE;
+ #ifdef GRUB_UTIL
+ /* If the Stage 2 is in a partition mounted by an OS, this will store
+ the filename under the OS. */
+ char *stage2_os_file = 0;
+ #endif /* GRUB_UTIL */
+-
+- /* Save the first sector of Stage2 in STAGE2_SECT. */
+- static void disk_read_savesect_func (int sector, int offset, int length)
+- {
+- if (debug)
+- printf ("[%d]", sector);
+-
+- /* ReiserFS has files which sometimes contain data not aligned
+- on sector boundaries. Returning an error is better than
+- silently failing. */
+- if (offset != 0 || length != SECTOR_SIZE)
+- errnum = ERR_UNALIGNED;
+-
+- saved_sector = sector;
+- }
+-
+- /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and
+- INSTALLSECT. */
+- static void disk_read_blocklist_func (int sector, int offset, int length)
+- {
+- if (debug)
+- printf("[%d]", sector);
+-
+- if (offset != 0 || last_length != SECTOR_SIZE)
+- {
+- /* We found a non-sector-aligned data block. */
+- errnum = ERR_UNALIGNED;
+- return;
+- }
+-
+- last_length = length;
+-
+- if (*((unsigned long *) (installlist - 4))
+- + *((unsigned short *) installlist) != sector
+- || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4)
+- {
+- installlist -= 8;
+-
+- if (*((unsigned long *) (installlist - 8)))
+- errnum = ERR_WONT_FIT;
+- else
+- {
+- *((unsigned short *) (installlist + 2)) = (installaddr >> 4);
+- *((unsigned long *) (installlist - 4)) = sector;
+- }
+- }
+-
+- *((unsigned short *) installlist) += 1;
+- installaddr += 512;
+- }
+
+ /* First, check the GNU-style long option. */
+ while (1)
+@@ -1987,10 +2049,10 @@
+ addr = skip_to (0, file);
+
+ /* Get the installation address. */
+- if (! safe_parse_maxint (&addr, &installaddr))
++ if (! safe_parse_maxint (&addr, installaddr))
+ {
+ /* ADDR is not specified. */
+- installaddr = 0;
++ *installaddr = 0;
+ ptr = addr;
+ errnum = 0;
+ }
+@@ -2084,17 +2146,17 @@
+ = (dest_drive & BIOS_FLAG_FIXED_DISK);
+
+ /* Read the first sector of Stage 2. */
+- disk_read_hook = disk_read_savesect_func;
+- if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)
++ disk_read_hook = install_savesect_helper;
++ if (grub_read (*stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+ goto fail;
+
+- stage2_first_sector = saved_sector;
++ stage2_first_sector = *saved_sector;
+
+ /* Read the second sector of Stage 2. */
+ if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+ goto fail;
+
+- stage2_second_sector = saved_sector;
++ stage2_second_sector = *saved_sector;
+
+ /* Check for the version of Stage 2. */
+ if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS))
+@@ -2110,27 +2172,27 @@
+
+ /* If INSTALLADDR is not specified explicitly in the command-line,
+ determine it by the Stage 2 id. */
+- if (! installaddr)
++ if (! *installaddr)
+ {
+ if (! is_stage1_5)
+ /* Stage 2. */
+- installaddr = 0x8000;
++ *installaddr = 0x8000;
+ else
+ /* Stage 1.5. */
+- installaddr = 0x2000;
++ *installaddr = 0x2000;
+ }
+
+ *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR))
+ = stage2_first_sector;
+ *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS))
+- = installaddr;
++ = *installaddr;
+ *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT))
+- = installaddr >> 4;
++ = *installaddr >> 4;
+
+- i = (int) stage2_first_buffer + SECTOR_SIZE - 4;
++ i = (int) *stage2_first_buffer + SECTOR_SIZE - 4;
+ while (*((unsigned long *) i))
+ {
+- if (i < (int) stage2_first_buffer
++ if (i < (int) *stage2_first_buffer
+ || (*((int *) (i - 4)) & 0x80000000)
+ || *((unsigned short *) i) >= 0xA00
+ || *((short *) (i + 2)) == 0)
+@@ -2144,13 +2206,13 @@
+ i -= 8;
+ }
+
+- installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4;
+- installaddr += SECTOR_SIZE;
++ *installlist = (int) *stage2_first_buffer + SECTOR_SIZE + 4;
++ *installaddr += SECTOR_SIZE;
+
+ /* Read the whole of Stage2 except for the first sector. */
+ grub_seek (SECTOR_SIZE);
+
+- disk_read_hook = disk_read_blocklist_func;
++ disk_read_hook = install_blocklist_helper;
+ if (! grub_read (dummy, -1))
+ goto fail;
+
+@@ -2233,7 +2295,7 @@
+ /* Skip the first sector. */
+ grub_seek (SECTOR_SIZE);
+
+- disk_read_hook = disk_read_savesect_func;
++ disk_read_hook = install_savesect_helper;
+ if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+ goto fail;
+
+@@ -2303,7 +2365,7 @@
+ else
+ #endif /* GRUB_UTIL */
+ {
+- if (! devwrite (saved_sector - part_start, 1, stage2_buffer))
++ if (! devwrite (*saved_sector - part_start, 1, stage2_buffer))
+ goto fail;
+ }
+ }
+@@ -2325,7 +2387,7 @@
+ goto fail;
+ }
+
+- if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
++ if (fwrite (*stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+ {
+ fclose (fp);
+ errnum = ERR_WRITE;
+@@ -2352,7 +2414,7 @@
+ goto fail;
+
+ if (! devwrite (stage2_first_sector - src_part_start, 1,
+- stage2_first_buffer))
++ *stage2_first_buffer))
+ goto fail;
+
+ if (! devwrite (stage2_second_sector - src_part_start, 1,
+diff -ur grub-0.96-orig/stage2/shared.h grub-0.96/stage2/shared.h
+--- grub-0.96-orig/stage2/shared.h 2005-03-10 02:28:24.754994000 -0600
++++ grub-0.96/stage2/shared.h 2005-03-10 03:24:03.590414640 -0600
+@@ -36,8 +36,8 @@
+
+ /* Maybe redirect memory requests through grub_scratch_mem. */
+ #ifdef GRUB_UTIL
+-extern char *grub_scratch_mem;
+-# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
++extern void *grub_scratch_mem;
++# define RAW_ADDR(x) ((x) + (unsigned long) grub_scratch_mem)
+ # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
+ #else
+ # define RAW_ADDR(x) (x)
diff --git a/sys-boot/grub/grub-0.96-r1.ebuild b/sys-boot/grub/grub-0.96-r1.ebuild
new file mode 100644
index 000000000000..f96491797145
--- /dev/null
+++ b/sys-boot/grub/grub-0.96-r1.ebuild
@@ -0,0 +1,155 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-0.96-r1.ebuild,v 1.1 2005/03/11 05:14:32 vapier Exp $
+
+inherit mount-boot eutils flag-o-matic toolchain-funcs
+
+DESCRIPTION="GNU GRUB boot loader"
+HOMEPAGE="http://www.gnu.org/software/grub/"
+SRC_URI="mirror://gentoo/${P}.tar.gz
+ ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz
+ mirror://gentoo/${PN}-0.95.20040823-splash.patch.bz2"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="-*"
+IUSE="static netboot"
+
+RDEPEND=">=sys-libs/ncurses-5.2-r5"
+DEPEND="${RDEPEND}
+ >=sys-devel/automake-1.7
+ >=sys-devel/autoconf-2.5"
+PROVIDE="virtual/bootloader"
+
+pkg_setup() {
+ if ! has_m32; then
+ eerror "Your compiler seems to be unable to compile 32bit code."
+ eerror "If you are on amd64, make sure you compile gcc with:"
+ echo
+ eerror " USE=multilib FEATURES=-sandbox"
+ die "Cannot produce 32bit objects!"
+ fi
+
+ ABI_ALLOW="x86"
+ ABI="x86"
+}
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+
+ epatch "${WORKDIR}"/${PN}-0.95.20040823-splash.patch
+
+ # PIC patch by psm & kevin f. quinn #80693
+ epatch "${FILESDIR}"/${P}-PIC.patch
+
+ # i2o RAID support #76143
+ epatch "${FILESDIR}"/${P}-i2o-raid.patch
+
+ # -fwritable-strings is deprecated; testing to see if we need it any more
+ epatch "${FILESDIR}"/${PN}-0.95.20040823-warnings.patch
+
+ # should fix NX segfaulting on amd64 and x86_64 by Peter Jones
+ # http://lists.gnu.org/archive/html/bug-grub/2005-03/msg00011.html
+ epatch "${FILESDIR}"/${P}-nxstack.patch
+
+ # a bunch of patches apply to raw autotool files
+ autoconf || die "autoconf failed"
+ aclocal || die "aclocal failed"
+ automake || die "automake failed"
+}
+
+src_compile() {
+ unset BLOCK_SIZE #73499
+
+ ### i686-specific code in the boot loader is a bad idea; disabling to ensure
+ ### at least some compatibility if the hard drive is moved to an older or
+ ### incompatible system.
+ unset CFLAGS
+
+ # grub-0.95 added -fno-stack-protector detection, to disable ssp for stage2,
+ # but the objcopy's (faulty) test fails if -fstack-protector is default.
+ # create a cache telling configure that objcopy is ok, and add -C to econf
+ # to make use of the cache.
+ #
+ # CFLAGS has to be undefined running econf, else -fno-stack-protector detection fails.
+ # STAGE2_CFLAGS is not allowed to be used on emake command-line, it overwrites
+ # -fno-stack-protector detected by configure, removed from netboot's emake.
+
+ append-flags -DNDEBUG
+ echo "grub_cv_prog_objcopy_absolute=yes" > config.cache #79734
+ use static && append-ldflags -static
+
+ # build the net-bootable grub first, but only if "netboot" is set
+ if use netboot ; then
+ CFLAGS="" \
+ econf \
+ --libdir=/lib \
+ --datadir=/usr/lib/grub \
+ --exec-prefix=/ \
+ --disable-auto-linux-mem-opt \
+ --enable-diskless \
+ --enable-{3c{5{03,07,09,29,95},90x},cs89x0,davicom,depca,eepro{,100}} \
+ --enable-{epic100,exos205,ni5210,lance,ne2100,ni{50,65}10,natsemi} \
+ --enable-{ne,ns8390,wd,otulip,rtl8139,sis900,sk-g16,smc9000,tiara} \
+ --enable-{tulip,via-rhine,w89c840} || die "netboot econf failed"
+
+ emake w89c840_o_CFLAGS="-O" || die "making netboot stuff"
+
+ mv -f stage2/{nbgrub,pxegrub} ${S}
+ mv -f stage2/stage2 stage2/stage2.netboot
+
+ make clean || die "make clean failed"
+ fi
+
+ # Now build the regular grub
+ # Note that FFS and UFS2 support are broken for now - stage1_5 files too big
+ CFLAGS="${CFLAGS}" \
+ econf \
+ --libdir=/lib \
+ --datadir=/usr/lib/grub \
+ --exec-prefix=/ \
+ --disable-auto-linux-mem-opt || die "econf failed"
+ emake || die "making regular stuff"
+}
+
+src_install() {
+ make DESTDIR="${D}" install || die
+ exeinto /usr/lib/grub
+ doexe stage2/stage2
+ use netboot && doexe nbgrub pxegrub stage2/stage2.netboot
+
+ insinto /boot/grub
+ doins "${FILESDIR}"/splash.xpm.gz
+ newins docs/menu.lst grub.conf.sample
+
+ dodoc AUTHORS BUGS COPYING ChangeLog NEWS README THANKS TODO
+ newdoc docs/menu.lst grub.conf.sample
+}
+
+pkg_postinst() {
+ [[ ${ROOT} != "/" ]] && return 0
+
+ # change menu.lst to grub.conf
+ if [[ ! -e /boot/grub/grub.conf && -e /boot/grub/menu.lst ]] ; then
+ mv -f /boot/grub/menu.lst /boot/grub/grub.conf
+ ewarn
+ ewarn "*** IMPORTANT NOTE: menu.lst has been renamed to grub.conf"
+ ewarn
+ fi
+ einfo "Linking from new grub.conf name to menu.lst"
+ [[ ! -e /boot/grub/menu.lst ]] && ln -snf grub.conf /boot/grub/menu.lst
+
+ [[ -e /boot/grub/stage2 ]] && mv /boot/grub/stage2{,.old}
+
+ einfo "Copying files from /usr/lib/grub to /boot"
+ for x in /lib/grub/*/* /usr/lib/grub/*/* ; do
+ [[ -f ${x} ]] && cp -p ${x} /boot/grub
+ done
+
+ [[ -e /boot/grub/grub.conf ]] \
+ && /sbin/grub \
+ --batch \
+ --device-map=/boot/grub/device.map \
+ < /boot/grub/grub.conf > /dev/null 2>&1
+}