All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] generic ELF loading #3
@ 2006-11-01  1:23 Hollis Blanchard
  2006-11-01 12:48 ` Johan Rydberg
  2006-11-02 19:58 ` [PATCH] generic ELF loading #3 Yoshinori K. Okuji
  0 siblings, 2 replies; 10+ messages in thread
From: Hollis Blanchard @ 2006-11-01  1:23 UTC (permalink / raw)
  To: grub-devel

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

Here is pass #3 of the ELF loader. Changes from #2:
- the `load' callback no longer modifies the phdr directly
- grub_elf_size() is now a standard function, and only considers PT_LOAD
segments
- grub_elf_phdr_iterate() is now static (though could be made global if
we need it somewhere in the future)
- better debugging output

(Again, since I will be replacing loader/i386/pc/multiboot in the near
future, I have not converted it to use the new infrastructure.)

I'm just going to include them as attachments this time because it's
easier. I have tested this code on PowerPC with both Mac and IBM
firmware, with both 32-bit and 64-bit vmlinux files.

I believe this addresses all comments, so if there are no more issues I
will check it in soon.

-Hollis

[-- Attachment #2: elf --]
[-- Type: text/x-patch, Size: 47710 bytes --]

Index: grub2-cvs/conf/i386-efi.mk
===================================================================
--- grub2-cvs.orig/conf/i386-efi.mk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/i386-efi.mk	2006-10-31 18:54:59.000000000 -0600
@@ -486,9 +486,9 @@ fs-kernel_mod-disk_efi_efidisk.lst: disk
 	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
 
 
-kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
-	pc_partition.h rescue.h symbol.h term.h types.h \
+kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h pc_partition.h rescue.h symbol.h term.h types.h \
 	i386/efi/time.h efi/efi.h efi/time.h efi/disk.h
 kernel_mod_CFLAGS = $(COMMON_CFLAGS)
 kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
Index: grub2-cvs/conf/i386-efi.rmk
===================================================================
--- grub2-cvs.orig/conf/i386-efi.rmk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/i386-efi.rmk	2006-10-31 18:54:59.000000000 -0600
@@ -43,7 +43,8 @@ grub_emu_SOURCES = commands/boot.c comma
 	fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c	\
 	fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c	\
 	io/gzio.c							\
-	kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c 	\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c							\
 	normal/execute.c kern/file.c kern/fs.c normal/lexer.c 		\
 	kern/loader.c kern/main.c kern/misc.c kern/parser.c		\
 	grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c	\
@@ -76,9 +77,9 @@ kernel_mod_SOURCES = kern/i386/efi/start
 	kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
 	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
 	term/efi/console.c disk/efi/efidisk.c
-kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
-	pc_partition.h rescue.h symbol.h term.h types.h \
+kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h pc_partition.h rescue.h symbol.h term.h types.h \
 	i386/efi/time.h efi/efi.h efi/time.h efi/disk.h
 kernel_mod_CFLAGS = $(COMMON_CFLAGS)
 kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
Index: grub2-cvs/conf/i386-pc.mk
===================================================================
--- grub2-cvs.orig/conf/i386-pc.mk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/i386-pc.mk	2006-10-31 18:54:59.000000000 -0600
@@ -162,9 +162,9 @@ kernel_img-symlist.o: symlist.c
 	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
 -include kernel_img-symlist.d
 
-kernel_img_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
-	pc_partition.h rescue.h symbol.h term.h types.h \
+kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h pc_partition.h rescue.h symbol.h term.h types.h \
 	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
 	machine/memory.h machine/loader.h machine/time.h machine/vga.h \
 	machine/vbe.h
Index: grub2-cvs/conf/i386-pc.rmk
===================================================================
--- grub2-cvs.orig/conf/i386-pc.rmk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/i386-pc.rmk	2006-10-31 18:54:59.000000000 -0600
@@ -30,9 +30,9 @@ kernel_img_SOURCES = kern/i386/pc/startu
 	kern/env.c disk/i386/pc/biosdisk.c \
 	term/i386/pc/console.c \
 	symlist.c
-kernel_img_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
-	pc_partition.h rescue.h symbol.h term.h types.h \
+kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h pc_partition.h rescue.h symbol.h term.h types.h \
 	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
 	machine/memory.h machine/loader.h machine/time.h machine/vga.h \
 	machine/vbe.h
@@ -89,7 +89,8 @@ grub_emu_SOURCES = commands/boot.c comma
 	fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c	\
 	fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c	\
 	io/gzio.c							\
-	kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c 	\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c							\
 	normal/execute.c kern/file.c kern/fs.c normal/lexer.c 		\
 	kern/loader.c kern/main.c kern/misc.c kern/parser.c		\
 	grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c	\
Index: grub2-cvs/conf/powerpc-ieee1275.mk
===================================================================
--- grub2-cvs.orig/conf/powerpc-ieee1275.mk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/powerpc-ieee1275.mk	2006-10-31 18:54:59.000000000 -0600
@@ -10,11 +10,10 @@ COMMON_LDFLAGS += -nostdlib
 MOSTLYCLEANFILES += kernel_elf_symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
 
-kernel_elf_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h symbol.h \
-	term.h types.h powerpc/libgcc.h loader.h \
-	partition.h pc_partition.h ieee1275/ieee1275.h machine/time.h \
-	machine/kernel.h
+kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
+	symbol.h term.h types.h powerpc/libgcc.h loader.h partition.h \
+	pc_partition.h ieee1275/ieee1275.h machine/time.h machine/kernel.h
 
 kernel_elf_symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh
 	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
@@ -63,9 +62,10 @@ grub_emu_SOURCES = commands/boot.c comma
 	fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c	\
 	fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c	\
 	io/gzio.c							\
-	kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c 	\
-	kern/file.c kern/fs.c kern/loader.c kern/main.c kern/misc.c	\
-	kern/parser.c kern/partition.c kern/rescue.c kern/term.c	\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c kern/loader.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/rescue.c	\
+	kern/term.c							\
 	normal/arg.c normal/cmdline.c normal/command.c			\
 	normal/completion.c normal/execute.c		 		\
 	normal/function.c normal/lexer.c normal/main.c normal/menu.c 	\
@@ -75,11 +75,11 @@ grub_emu_SOURCES = commands/boot.c comma
 	util/console.c util/grub-emu.c util/misc.c			\
 	util/i386/pc/biosdisk.c util/i386/pc/getroot.c			\
 	util/powerpc/ieee1275/misc.c grub_script.tab.c grub_emu_init.c
-CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
-MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_help.d grub_emu-commands_search.d grub_emu-commands_terminal.d grub_emu-commands_test.d grub_emu-commands_ls.d grub_emu-commands_blocklist.d grub_emu-commands_ieee1275_halt.d grub_emu-commands_ieee1275_reboot.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_ext2.d grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_hfsplus.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_completion.d grub_emu-normal_execute.d grub_emu-normal_function.d grub_emu-normal_lexer.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d grub_emu-util_i386_pc_getroot.d grub_emu-util_powerpc_ieee1275_misc.d grub_emu-grub_script_tab.d grub_emu-grub_emu_init.d
+CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_help.d grub_emu-commands_search.d grub_emu-commands_terminal.d grub_emu-commands_test.d grub_emu-commands_ls.d grub_emu-commands_blocklist.d grub_emu-commands_ieee1275_halt.d grub_emu-commands_ieee1275_reboot.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_ext2.d grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_hfsplus.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_completion.d grub_emu-normal_execute.d grub_emu-normal_function.d grub_emu-normal_lexer.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d grub_emu-util_i386_pc_getroot.d grub_emu-util_powerpc_ieee1275_misc.d grub_emu-grub_script_tab.d grub_emu-grub_emu_init.d
 
-grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
-	$(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS)
+grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+	$(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS)
 
 grub_emu-commands_boot.o: commands/boot.c
 	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
@@ -197,6 +197,10 @@ grub_emu-kern_dl.o: kern/dl.c
 	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
 -include grub_emu-kern_dl.d
 
+grub_emu-kern_elf.o: kern/elf.c
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
 grub_emu-kern_env.o: kern/env.c
 	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
 -include grub_emu-kern_env.d
@@ -346,17 +350,17 @@ grub_emu_LDFLAGS = $(LIBCURSES)
 
 kernel_elf_SOURCES = kern/powerpc/ieee1275/crt0.S kern/powerpc/ieee1275/cmain.c \
 	kern/ieee1275/ieee1275.c kern/main.c kern/device.c 		\
-	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c 		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c 		\
 	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c 	\
 	kern/powerpc/ieee1275/init.c term/ieee1275/ofconsole.c 		\
 	kern/powerpc/ieee1275/openfw.c disk/ieee1275/ofdisk.c 		\
 	kern/parser.c kern/partition.c kern/env.c kern/powerpc/dl.c 	\
 	kernel_elf_symlist.c kern/powerpc/cache.S
-CLEANFILES += kernel.elf kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o
-MOSTLYCLEANFILES += kernel_elf-kern_powerpc_ieee1275_crt0.d kernel_elf-kern_powerpc_ieee1275_cmain.d kernel_elf-kern_ieee1275_ieee1275.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_powerpc_ieee1275_init.d kernel_elf-term_ieee1275_ofconsole.d kernel_elf-kern_powerpc_ieee1275_openfw.d kernel_elf-disk_ieee1275_ofdisk.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_env.d kernel_elf-kern_powerpc_dl.d kernel_elf-kernel_elf_symlist.d kernel_elf-kern_powerpc_cache.d
+CLEANFILES += kernel.elf kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o
+MOSTLYCLEANFILES += kernel_elf-kern_powerpc_ieee1275_crt0.d kernel_elf-kern_powerpc_ieee1275_cmain.d kernel_elf-kern_ieee1275_ieee1275.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_err.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_powerpc_ieee1275_init.d kernel_elf-term_ieee1275_ofconsole.d kernel_elf-kern_powerpc_ieee1275_openfw.d kernel_elf-disk_ieee1275_ofdisk.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_env.d kernel_elf-kern_powerpc_dl.d kernel_elf-kernel_elf_symlist.d kernel_elf-kern_powerpc_cache.d
 
-kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o
-	$(TARGET_CC) -o $@ kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS)
+kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o
+	$(TARGET_CC) -o $@ kernel_elf-kern_powerpc_ieee1275_crt0.o kernel_elf-kern_powerpc_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_powerpc_ieee1275_init.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_powerpc_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kernel_elf_symlist.o kernel_elf-kern_powerpc_cache.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS)
 
 kernel_elf-kern_powerpc_ieee1275_crt0.o: kern/powerpc/ieee1275/crt0.S
 	$(TARGET_CC) -Ikern/powerpc/ieee1275 -I$(srcdir)/kern/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
@@ -386,6 +390,10 @@ kernel_elf-kern_dl.o: kern/dl.c
 	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
 -include kernel_elf-kern_dl.d
 
+kernel_elf-kern_err.o: kern/err.c
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
+-include kernel_elf-kern_err.d
+
 kernel_elf-kern_file.o: kern/file.c
 	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
 -include kernel_elf-kern_file.d
@@ -394,10 +402,6 @@ kernel_elf-kern_fs.o: kern/fs.c
 	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
 -include kernel_elf-kern_fs.d
 
-kernel_elf-kern_err.o: kern/err.c
-	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
--include kernel_elf-kern_err.d
-
 kernel_elf-kern_misc.o: kern/misc.c
 	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $<
 -include kernel_elf-kern_misc.d
Index: grub2-cvs/conf/powerpc-ieee1275.rmk
===================================================================
--- grub2-cvs.orig/conf/powerpc-ieee1275.rmk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/powerpc-ieee1275.rmk	2006-10-31 18:54:59.000000000 -0600
@@ -10,11 +10,10 @@ COMMON_LDFLAGS += -nostdlib
 MOSTLYCLEANFILES += kernel_elf_symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
 
-kernel_elf_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h symbol.h \
-	term.h types.h powerpc/libgcc.h loader.h \
-	partition.h pc_partition.h ieee1275/ieee1275.h machine/time.h \
-	machine/kernel.h
+kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
+	symbol.h term.h types.h powerpc/libgcc.h loader.h partition.h \
+	pc_partition.h ieee1275/ieee1275.h machine/time.h machine/kernel.h
 
 kernel_elf_symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh
 	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
@@ -45,9 +44,10 @@ grub_emu_SOURCES = commands/boot.c comma
 	fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c	\
 	fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c	\
 	io/gzio.c							\
-	kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c 	\
-	kern/file.c kern/fs.c kern/loader.c kern/main.c kern/misc.c	\
-	kern/parser.c kern/partition.c kern/rescue.c kern/term.c	\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c kern/loader.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/rescue.c	\
+	kern/term.c							\
 	normal/arg.c normal/cmdline.c normal/command.c			\
 	normal/completion.c normal/execute.c		 		\
 	normal/function.c normal/lexer.c normal/main.c normal/menu.c 	\
@@ -62,7 +62,7 @@ grub_emu_LDFLAGS = $(LIBCURSES)
 
 kernel_elf_SOURCES = kern/powerpc/ieee1275/crt0.S kern/powerpc/ieee1275/cmain.c \
 	kern/ieee1275/ieee1275.c kern/main.c kern/device.c 		\
-	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c 		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c 		\
 	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c 	\
 	kern/powerpc/ieee1275/init.c term/ieee1275/ofconsole.c 		\
 	kern/powerpc/ieee1275/openfw.c disk/ieee1275/ofdisk.c 		\
Index: grub2-cvs/conf/sparc64-ieee1275.mk
===================================================================
--- grub2-cvs.orig/conf/sparc64-ieee1275.mk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/sparc64-ieee1275.mk	2006-10-31 18:54:59.000000000 -0600
@@ -10,11 +10,10 @@ COMMON_LDFLAGS = -melf64_sparc -nostdlib
 MOSTLYCLEANFILES += kernel_elf_symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
 
-kernel_elf_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h symbol.h \
-	term.h types.h sparc64/libgcc.h loader.h \
-	partition.h pc_partition.h ieee1275/ieee1275.h machine/time.h \
-	machine/kernel.h
+kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
+	symbol.h term.h types.h sparc64/libgcc.h loader.h partition.h \
+	pc_partition.h ieee1275/ieee1275.h machine/time.h machine/kernel.h
 
 kernel_elf_symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh
 	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
Index: grub2-cvs/conf/sparc64-ieee1275.rmk
===================================================================
--- grub2-cvs.orig/conf/sparc64-ieee1275.rmk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/sparc64-ieee1275.rmk	2006-10-31 18:54:59.000000000 -0600
@@ -10,11 +10,10 @@ COMMON_LDFLAGS = -melf64_sparc -nostdlib
 MOSTLYCLEANFILES += kernel_elf_symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst
 
-kernel_elf_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
-	file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h symbol.h \
-	term.h types.h sparc64/libgcc.h loader.h \
-	partition.h pc_partition.h ieee1275/ieee1275.h machine/time.h \
-	machine/kernel.h
+kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
+	symbol.h term.h types.h sparc64/libgcc.h loader.h partition.h \
+	pc_partition.h ieee1275/ieee1275.h machine/time.h machine/kernel.h
 
 kernel_elf_symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh
 	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
Index: grub2-cvs/include/grub/elfload.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ grub2-cvs/include/grub/elfload.h	2006-10-31 18:54:59.000000000 -0600
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_ELFLOAD_HEADER
+#define GRUB_ELFLOAD_HEADER	1
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_elf_file
+{
+  grub_file_t file;
+  union {
+    Elf64_Ehdr ehdr64;
+    Elf32_Ehdr ehdr32;
+  } ehdr;
+  void *phdrs;
+};
+typedef struct grub_elf_file *grub_elf_t;
+
+typedef int (*grub_elf32_load_hook_t) (Elf32_Phdr *phdr, grub_addr_t *addr);
+typedef int (*grub_elf64_load_hook_t) (Elf64_Phdr *phdr, grub_addr_t *addr);
+
+grub_elf_t grub_elf_open (const char *);
+grub_elf_t grub_elf_file (grub_file_t);
+grub_err_t grub_elf_close (grub_elf_t);
+
+int grub_elf_is_elf32 (grub_elf_t);
+grub_size_t grub_elf32_size (grub_elf_t);
+grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t);
+
+int grub_elf_is_elf64 (grub_elf_t);
+grub_size_t grub_elf64_size (grub_elf_t);
+grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t);
+
+#endif /* ! GRUB_ELFLOAD_HEADER */
Index: grub2-cvs/kern/elf.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ grub2-cvs/kern/elf.c	2006-10-31 19:10:32.000000000 -0600
@@ -0,0 +1,387 @@
+/* elf.c - load ELF files */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* Check if EHDR is a valid ELF header.  */
+static grub_err_t
+grub_elf_check_header (grub_elf_t elf)
+{
+  Elf32_Ehdr *e = &elf->ehdr.ehdr32;
+
+  if (e->e_ident[EI_MAG0] != ELFMAG0
+      || e->e_ident[EI_MAG1] != ELFMAG1
+      || e->e_ident[EI_MAG2] != ELFMAG2
+      || e->e_ident[EI_MAG3] != ELFMAG3
+      || e->e_ident[EI_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_elf_close (grub_elf_t elf)
+{
+  grub_file_t file = elf->file;
+
+  grub_free (elf->phdrs);
+  grub_free (elf);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+grub_elf_t
+grub_elf_file (grub_file_t file)
+{
+  grub_elf_t elf;
+
+  elf = grub_malloc (sizeof (*elf));
+  if (! elf)
+    return 0;
+
+  elf->file = file;
+  elf->phdrs = 0;
+
+  if (grub_file_read (elf->file, (char *) &elf->ehdr, sizeof (elf->ehdr))
+      != sizeof (elf->ehdr))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header.");
+      goto fail;
+    }
+
+  if (grub_elf_check_header (elf))
+    goto fail;
+
+  return elf;
+
+fail:
+  grub_elf_close (elf);
+  return 0;
+}
+
+grub_elf_t
+grub_elf_open (const char *name)
+{
+  grub_file_t file;
+
+  file = grub_gzfile_open (name, 1);
+  if (! file)
+    return 0;
+
+  return grub_elf_file (file);
+}
+
+\f
+/* 32-bit */
+
+int
+grub_elf_is_elf32 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+static int
+grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook)
+{
+  grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook;
+  grub_addr_t load_addr;
+
+  if (phdr->p_type != PT_LOAD)
+    return 0;
+
+  load_addr = phdr->p_paddr;
+  if (load_hook && load_hook (phdr, &load_addr))
+    return 1;
+
+  grub_dprintf ("elf", "Loading segment at %llx, size 0x%llx\n",
+		(unsigned long long) load_addr,
+		(unsigned long long) phdr->p_filesz);
+
+  if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+    {
+      return grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
+    }
+
+  if (grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz)
+      != (grub_ssize_t) phdr->p_filesz)
+    {
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't load segment");
+    }
+
+  if (phdr->p_filesz < phdr->p_memsz)
+    grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+		 0, phdr->p_memsz - phdr->p_filesz);
+
+  return 0;
+}
+
+static grub_err_t
+grub_elf32_load_phdrs (grub_elf_t elf)
+{
+  grub_ssize_t phdrs_size;
+
+  phdrs_size = elf->ehdr.ehdr32.e_phnum * elf->ehdr.ehdr32.e_phentsize;
+
+  grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%x.\n",
+		(unsigned long long) elf->ehdr.ehdr32.e_phoff,
+		phdrs_size);
+
+  elf->phdrs = grub_malloc (phdrs_size);
+  if (! elf->phdrs)
+    return grub_errno;
+
+  if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1)
+      || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
+    return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_elf32_phdr_iterate (grub_elf_t elf,
+			 int (*hook) (grub_elf_t, Elf32_Phdr *, void *),
+			 void *hook_arg)
+{
+  Elf32_Phdr *phdrs;
+  unsigned int i;
+
+  if (! elf->phdrs)
+    if (grub_elf32_load_phdrs (elf))
+      return grub_errno;
+  phdrs = elf->phdrs;
+
+  for (i = 0; i < elf->ehdr.ehdr32.e_phnum; i++)
+    {
+      Elf32_Phdr *phdr = phdrs + i;
+      grub_dprintf ("elf", "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx.\n",
+		    i, phdr->p_type,
+		    (unsigned long) phdr->p_paddr,
+		    (unsigned long) phdr->p_memsz);
+      if (hook (elf, phdr, hook_arg))
+	break;
+    }
+
+  return grub_errno;
+}
+
+/* Calculate the amount of memory spanned by the segments.  */
+grub_size_t
+grub_elf32_size (grub_elf_t elf)
+{
+  Elf32_Addr segments_start = (Elf32_Addr) -1;
+  Elf32_Addr segments_end = 0;
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+   * should claim.  */
+  auto int calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg);
+  int calcsize (grub_elf_t __unused _elf, Elf32_Phdr *phdr, void __unused *_arg)
+    {
+      /* Only consider loadable segments.  */
+      if (phdr->p_type != PT_LOAD)
+	return 0;
+      nr_phdrs++;
+      if (phdr->p_paddr < segments_start)
+	segments_start = phdr->p_paddr;
+      if (phdr->p_paddr + phdr->p_memsz > segments_end)
+	segments_end = phdr->p_paddr + phdr->p_memsz;
+      return 0;
+    }
+
+  grub_elf32_phdr_iterate (elf, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "No program headers present");
+      return 0;
+    }
+
+  if (segments_end < segments_start)
+    {
+      /* Very bad addresses.  */
+      grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
+      return 0;
+    }
+
+  return segments_end - segments_start;
+}
+
+
+/* Load every loadable segment into memory specified by `load_hook'.  */
+grub_err_t
+grub_elf32_load (grub_elf_t elf, grub_elf32_load_hook_t load_hook)
+{
+  return grub_elf32_phdr_iterate (elf, grub_elf32_load_segment, load_hook);
+}
+
+
+\f
+/* 64-bit */
+
+int
+grub_elf_is_elf64 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+static int
+grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *hook)
+{
+  grub_elf64_load_hook_t load_hook = (grub_elf64_load_hook_t) hook;
+  grub_addr_t load_addr;
+
+  if (phdr->p_type != PT_LOAD)
+    return 0;
+
+  load_addr = phdr->p_paddr;
+  if (load_hook && load_hook (phdr, &load_addr))
+    return 1;
+
+  grub_dprintf ("elf", "Loading segment at %llx, size 0x%llx\n",
+		(unsigned long long) load_addr,
+		(unsigned long long) phdr->p_filesz);
+
+  if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+    {
+      return grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
+    }
+
+  if (grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz)
+      != (grub_ssize_t) phdr->p_filesz)
+    {
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't load segment");
+    }
+
+  if (phdr->p_filesz < phdr->p_memsz)
+    grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+		 0, phdr->p_memsz - phdr->p_filesz);
+
+  return 0;
+}
+
+static grub_err_t
+grub_elf64_load_phdrs (grub_elf_t elf)
+{
+  grub_ssize_t phdrs_size;
+
+  phdrs_size = elf->ehdr.ehdr64.e_phnum * elf->ehdr.ehdr64.e_phentsize;
+
+  grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%x.\n",
+		(unsigned long long) elf->ehdr.ehdr64.e_phoff,
+		phdrs_size);
+
+  elf->phdrs = grub_malloc (phdrs_size);
+  if (! elf->phdrs)
+    return grub_errno;
+
+  if ((grub_file_seek (elf->file, elf->ehdr.ehdr64.e_phoff) == (grub_off_t) -1)
+      || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
+    return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_elf64_phdr_iterate (grub_elf_t elf,
+			 int (*hook) (grub_elf_t, Elf64_Phdr *, void *),
+			 void *hook_arg)
+{
+  Elf64_Phdr *phdrs;
+  unsigned int i;
+
+  if (! elf->phdrs)
+    if (grub_elf64_load_phdrs (elf))
+      return grub_errno;
+  phdrs = elf->phdrs;
+
+  for (i = 0; i < elf->ehdr.ehdr64.e_phnum; i++)
+    {
+      Elf64_Phdr *phdr = phdrs + i;
+      grub_dprintf ("elf", "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx.\n",
+		    i, phdr->p_type,
+		    (unsigned long) phdr->p_paddr,
+		    (unsigned long) phdr->p_memsz);
+      if (hook (elf, phdr, hook_arg))
+	break;
+    }
+
+  return grub_errno;
+}
+
+/* Calculate the amount of memory spanned by the segments.  */
+grub_size_t
+grub_elf64_size (grub_elf_t elf)
+{
+  Elf64_Addr segments_start = (Elf64_Addr) -1;
+  Elf64_Addr segments_end = 0;
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+   * should claim.  */
+  auto int calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
+  int calcsize (grub_elf_t __unused _elf, Elf64_Phdr *phdr, void __unused *_arg)
+    {
+      /* Only consider loadable segments.  */
+      if (phdr->p_type != PT_LOAD)
+	return 0;
+      nr_phdrs++;
+      if (phdr->p_paddr < segments_start)
+	segments_start = phdr->p_paddr;
+      if (phdr->p_paddr + phdr->p_memsz > segments_end)
+	segments_end = phdr->p_paddr + phdr->p_memsz;
+      return 0;
+    }
+
+  grub_elf64_phdr_iterate (elf, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "No program headers present");
+      return 0;
+    }
+
+  if (segments_end < segments_start)
+    {
+      /* Very bad addresses.  */
+      grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
+      return 0;
+    }
+
+  return segments_end - segments_start;
+}
+
+
+/* Load every loadable segment into memory specified by `load_hook'.  */
+grub_err_t
+grub_elf64_load (grub_elf_t elf, grub_elf64_load_hook_t load_hook)
+{
+  return grub_elf64_phdr_iterate (elf, grub_elf64_load_segment, load_hook);
+}
+
Index: grub2-cvs/conf/common.rmk
===================================================================
--- grub2-cvs.orig/conf/common.rmk	2006-10-31 18:54:54.000000000 -0600
+++ grub2-cvs/conf/common.rmk	2006-10-31 18:54:59.000000000 -0600
@@ -213,7 +213,12 @@ blocklist_mod_CFLAGS = $(COMMON_CFLAGS)
 blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # Misc.
-pkgdata_MODULES += gzio.mod 
+pkgdata_MODULES += gzio.mod elf.mod
+
+# For elf.mod.
+elf_mod_SOURCES = kern/elf.c
+elf_mod_CFLAGS = $(COMMON_CFLAGS)
+elf_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For gzio.mod.
 gzio_mod_SOURCES = io/gzio.c
Index: grub2-cvs/include/grub/types.h
===================================================================
--- grub2-cvs.orig/include/grub/types.h	2006-10-31 19:06:47.000000000 -0600
+++ grub2-cvs/include/grub/types.h	2006-10-31 19:06:58.000000000 -0600
@@ -23,6 +23,8 @@
 #include <config.h>
 #include <grub/cpu/types.h>
 
+#define __unused __attribute__ ((unused))
+
 #ifdef GRUB_UTIL
 # define GRUB_CPU_SIZEOF_VOID_P	SIZEOF_VOID_P
 # define GRUB_CPU_SIZEOF_LONG	SIZEOF_LONG

[-- Attachment #3: linux-ppc-elf64 --]
[-- Type: text/x-patch, Size: 8145 bytes --]

Index: grub2-cvs/loader/powerpc/ieee1275/linux.c
===================================================================
--- grub2-cvs.orig/loader/powerpc/ieee1275/linux.c	2006-10-31 17:05:16.000000000 -0600
+++ grub2-cvs/loader/powerpc/ieee1275/linux.c	2006-10-31 17:05:19.000000000 -0600
@@ -19,6 +19,7 @@
  */
 
 #include <grub/elf.h>
+#include <grub/elfload.h>
 #include <grub/loader.h>
 #include <grub/dl.h>
 #include <grub/mm.h>
@@ -27,10 +28,12 @@
 #include <grub/ieee1275/ieee1275.h>
 #include <grub/machine/loader.h>
 
+#define ELF32_LOADMASK (0xc0000000UL)
+#define ELF64_LOADMASK (0xc000000000000000ULL)
+
 static grub_dl_t my_mod;
 
 static int loaded;
-static int vmlinux;
 
 static grub_addr_t initrd_addr;
 static grub_size_t initrd_size;
@@ -97,124 +100,131 @@ grub_linux_unload (void)
   return err;
 }
 
-void
-grub_rescue_cmd_linux (int argc, char *argv[])
+static grub_err_t
+grub_linux_load32 (grub_elf_t elf)
 {
-  grub_file_t file = 0;
-  Elf32_Ehdr ehdr;
-  Elf32_Phdr *phdrs = 0;
-  int i;
-  int offset = 0;
-  grub_addr_t entry;
+  Elf32_Addr entry;
   int found_addr = 0;
-  int size;
-  char *dest;
-
-  grub_dl_ref (my_mod);
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  if (grub_file_read (file, (char *) &ehdr, sizeof (ehdr)) != sizeof (ehdr))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux elf header");
-      goto fail;
-    }
 
-  if (grub_dl_check_header (&ehdr, sizeof(ehdr)))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
-      goto fail;
-    }
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
+  if (entry == 0)
+    entry = 0x01400000;
+
+  linux_size = grub_elf32_size (elf);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
 
-  if (ehdr.e_type != ET_EXEC)
+  /* On some systems, firmware occupies the memory we're trying to use.
+   * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
+   * until we find an open area.  */
+  for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)
     {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-		  "This ELF file is not of the right type\n");
-      goto fail;
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+		    linux_addr, linux_size);
+      found_addr = grub_claimmap (linux_addr, linux_size);
+      if (found_addr != -1)
+	break;
     }
+  if (found_addr == -1)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
 
-  /* Read the sections.  */
-  entry = ehdr.e_entry;
-  if (entry == 0xc0000000)
-    {
-      entry = 0x01400000;
-      vmlinux = 1;
+  /* Now load the segments into the area we claimed.  */
+  auto int offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr);
+  int offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr)
+    {
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (phdr->p_paddr & ~ELF32_LOADMASK) + linux_addr;
+      return 0;
     }
-  else
-    vmlinux = 0;
-
-  phdrs = (Elf32_Phdr *) grub_malloc (ehdr.e_phnum * ehdr.e_phentsize);
-  grub_file_read (file, (void *) phdrs, ehdr.e_phnum * ehdr.e_phentsize);
-
-  /* Release the previously used memory.  */
-  grub_loader_unset ();
+  return grub_elf32_load (elf, offset_phdr);
+}
 
-  /* Determine the amount of memory that is required.  */
-  linux_size = 0;
-  for (i = 0; i < ehdr.e_phnum; i++)
-    {
-      Elf32_Phdr *phdr = phdrs + i;
-      /* XXX: Is this calculation correct?  */
-      linux_size += phdr->p_memsz + phdr->p_filesz;
-    }
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf)
+{
+  Elf64_Addr entry;
+  int found_addr = 0;
 
-  /* Reserve memory for the kernel.  */
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
+  if (entry == 0)
+    entry = 0x01400000;
+
+  linux_size = grub_elf64_size (elf);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
   linux_size += 0x100000;
 
-  /* For some vmlinux kernels the address set above won't work.  Just
-     try some other addresses just like yaboot does.  */
+  /* On some systems, firmware occupies the memory we're trying to use.
+   * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
+   * until we find an open area.  */
   for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)
     {
-      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", 
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
 		    linux_addr, linux_size);
       found_addr = grub_claimmap (linux_addr, linux_size);
       if (found_addr != -1)
 	break;
     }
-
   if (found_addr == -1)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
-      goto fail;
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
+
+  /* Now load the segments into the area we claimed.  */
+  auto int offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr);
+  int offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr)
+    {
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (phdr->p_paddr & ~ELF64_LOADMASK) + linux_addr;
+      return 0;
     }
-  entry = linux_addr;
+  return grub_elf64_load (elf, offset_phdr);
+}
 
-  /* Load every loadable segment in memory.  */
-  for (i = 0; i < ehdr.e_phnum; i++)
-    {
-      Elf32_Phdr *phdr = phdrs + i;
+void
+grub_rescue_cmd_linux (int argc, char *argv[])
+{
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  char *dest;
 
-      if (phdr->p_type == PT_LOAD)
-	{
-	  void *segment_addr = ((char *) entry) + offset;
+  grub_dl_ref (my_mod);
 
-	  if (grub_file_seek (file, phdr->p_offset) == (grub_off_t) -1)
-	    {
-	      grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
-	      goto fail;
-	    }
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto out;
+    }
 
-	  grub_dprintf ("loader", "Loading segment %d at %p, size 0x%x\n", i,
-			segment_addr, phdr->p_filesz);
+  elf = grub_elf_open (argv[0]);
+  if (! elf)
+    goto out;
 
-	  if (grub_file_read (file, segment_addr, phdr->p_filesz)
-	      != (grub_ssize_t) phdr->p_filesz)
-	    goto fail;
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+		  "This ELF file is not of the right type\n");
+      goto out;
+    }
 
-	  if (phdr->p_filesz < phdr->p_memsz)
-	    grub_memset ((char *) (((char *) entry) + offset) + phdr->p_filesz, 0,
-			 phdr->p_memsz - phdr->p_filesz);
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
 
-	  offset += phdr->p_filesz;
-	}
+  if (grub_elf_is_elf32 (elf))
+    grub_linux_load32 (elf);
+  else
+  if (grub_elf_is_elf64 (elf))
+    grub_linux_load64 (elf);
+  else
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class");
+      goto out;
     }
 
   size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]);
@@ -223,7 +233,7 @@ grub_rescue_cmd_linux (int argc, char *a
 
   linux_args = grub_malloc (size);
   if (! linux_args)
-    goto fail;
+    goto out;
 
   /* Specify the boot file.  */
   dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
@@ -235,12 +245,10 @@ grub_rescue_cmd_linux (int argc, char *a
       dest = grub_stpcpy (dest, argv[i]);
     }
 
- fail:
+out:
 
-  if (file)
-    grub_file_close (file);
-
-  grub_free (phdrs);
+  if (elf)
+    grub_elf_close (elf);
 
   if (grub_errno != GRUB_ERR_NONE)
     {
@@ -254,8 +262,6 @@ grub_rescue_cmd_linux (int argc, char *a
       initrd_addr = 0;
       loaded = 1;
     }
-
-  return;
 }
 
 void

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2006-11-09 19:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-01  1:23 [PATCH] generic ELF loading #3 Hollis Blanchard
2006-11-01 12:48 ` Johan Rydberg
2006-11-03 20:45   ` __unused Hollis Blanchard
2006-11-04  3:44     ` __unused Johan Rydberg
2006-11-08 23:10     ` __unused Jeroen Dekkers
2006-11-09 15:31       ` __unused Johan Rydberg
2006-11-09 19:42         ` __unused Jeroen Dekkers
2006-11-02 19:58 ` [PATCH] generic ELF loading #3 Yoshinori K. Okuji
2006-11-02 20:54   ` Hollis Blanchard
2006-11-02 21:23     ` Hollis Blanchard

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.